cdrtools 「cdrecord で CDを焼く」+ 「cdda2wav と lame で MP3をエンコードする」

cdrecordを Linuxで使ってみました

最近の cdrecordは cdrtools というパッケージの 一部となっています
タイトルは 「CDを焼く」とありますが cdrtools をインストールする解説がメインです

cdrecordとは

UNIX系定番の CD焼きツール
もともと SCSIプロトコルを利用するため SCSI接続のCDドライブや
SCSIプロトコルを流用する USB接続のCDドライブ(USB1.1では間違いなく不安定)が対象となります

ATA接続の CDドライブに対しては下記のように対応できます
Linux-2.4系は SCSIエミュレーションを有効にすることで対応します
Linux-2.6系は SCSIエミュレーションの機能が取り込まれた形となって オプションとして指定不要です

特定機種のCDドライブについては cdrecord内部ドライバとして特別に対応されているようです

前準備

Linux-2.4系では 前述のとおり カーネルにて以下のオプションを有効にします
SCSIドライバが導入されていること ATA(IDE)ドライブを使うなら SCSIエミュレーション も必要

  • Device Drivers→SCSI device support→SCSI CDROM support
  • Device Drivers→ATA/ATAPI/MFM/RLL support→SCSI emulation support

cdrtoolsのバージョンについて

cdrtools-2.01 (少し古い 2008年のときの情報) と
cdrtools-3.00 (2011年 Linux-2.6.30.5) のインストール手順を説明していきます
いずれも FTPサイト からソースコードを取得できます

また cdrtools 両方のバージョンに共通していますが
CD-ROMデバイスは /dev/hda〜hdz のいずれかである前提で動作する仕様になっています

筆者の検証環境では devfs / udev のカスタマイズにより /dev/cdroms/cdrom0〜cdrom7 に
デバイスが割り当てる環境設定としているため
通常のビルドでは CD/DVDデバイスを見つけることができない cdrtoolsが完成します
こういった特殊環境への対応も解説の中で説明しています

cdrtools-2.01のインストール

ソースコードを一時ディレクトリに展開した後
/dev/cdroms/cdrom0〜7 に対応するための パッチ を当てます

$ tar -xzf cdrtools-2.01.tar.gz
$ cd cdrtools-2.01
$ zcat ../cdrtools-2.01_patch_devname.patch.gz | patch -p1
patching file libscg/scsi-linux-sg.c
$
 

パッチは scsi-linux-sg.c に対して更新を行います
/dev/hd* に加えて /dev/cdroms/cdrom* も認識できるようになります

他に特異な環境の方がいて /dev/cdroms/cdrom* とも異なる環境ならば
パッチの中身を参照して適切に書き換えれば対応できるでしょう (パッチ自体は軽量です)

次に ビルドに移りますが configureスクリプトを直接叩く方式ではありません
DEFAULTS/Default.linux を編集して DEFCCOM と INS_BASE を設定します

###########################################################################
#
# Compiler stuff
#
###########################################################################
#DEFCCOM=        cc
DEFCCOM=       gcc
###########################################################################
#
# If the next line is commented out, compilation is done with max warn level
# If the next line is uncommented, compilation is done with minimal warnings
#
###########################################################################
CWARNOPTS=

DEFINCDIRS=     $(SRCROOT)/include /usr/src/linux/include
LDPATH=         -L/opt/schily/lib
RUNPATH=        -R $(INS_BASE)/lib -R /opt/schily/lib -R $(OLIBSDIR)

###########################################################################
#
# Installation config stuff
#
###########################################################################
INS_BASE=       /usr/local
INS_KBASE=      /
 

DEFCCOMはコンパイラの指定です cc が存在しない環境でエラーを回避するため gccを明示します
INS_BASEは インストール場所の指定となります

後は 普通に make ; make install するだけです

$ make
〜
〜
make[1]: Leaving directory `/home/admin/cdrtools-2.01/scgskeleton'
        ==> MAKING "all" ON SUBDIRECTORY "SRCROOT/man"
make[1]: Entering directory `/home/admin/cdrtools-2.01/man'
        ==> MAKING "all" ON SUBDIRECTORY "SRCROOT/man/man4"
make[2]: Entering directory `/home/admin/cdrtools-2.01/man/man4'
        ==> MAKING "all" ON SUBCOMPONENT "SRCROOT/man/man4/makefiles.mk"
make[3]: Entering directory `/home/admin/cdrtools-2.01/man/man4'
make[3]: `all' に対して行うべき事はありません。
make[3]: Leaving directory `/home/admin/cdrtools-2.01/man/man4'
        ==> MAKING "all" ON SUBCOMPONENT "SRCROOT/man/man4/makerules.mk"
make[3]: Entering directory `/home/admin/cdrtools-2.01/man/man4'
make[3]: `all' に対して行うべき事はありません。
make[3]: Leaving directory `/home/admin/cdrtools-2.01/man/man4'
make[2]: Leaving directory `/home/admin/cdrtools-2.01/man/man4'
make[1]: Leaving directory `/home/admin/cdrtools-2.01/man'
$ su
# make install

cdrtools-3.00のインストール

ソースコードを一時ディレクトリに展開した後
/dev/cdroms/cdrom0〜7 に対応するための パッチ を当てます

$ tar -xjf cdrtools-3.00.tar.bz2
$ cd cdrtools-3.00
$ zcat ../cdrtools-3.00_patch_devname.patch.gz | patch -p1
patching file libscg/scsi-linux-sg.c
$
 

パッチは cdrtools-2.01の物とほぼ同じ内容で scsi-linux-sg.c に対して更新を行います
/dev/hd* に加えて /dev/cdroms/cdrom* も認識できるようになります

次に ビルドに移りますが configureスクリプトを直接叩く方式ではありません
makeコマンドを直接叩きます

$ make CCOM=gcc
RULES/rules.top:43: RULES/ldummy.lnk: そのようなファイルやディレクトリはありません
                W A R N I N G   Messages like:

gmake[2]: Entering directory `/tmp/cdrtools-2.01/libschily'
../RULES/r-gmake.dep:76: OBJ//cvmod.d: No such file or directory
../RULES/r-gmake.dep:76: OBJ//dat.d: No such file or directory

〜

        ==> LOCALIZING "OBJ/amd-turion-tm--64-mobile-technology-mt-37-linux-gcc/man/makefiles.5"
make[3]: Leaving directory `/home/admin/cdrtools-3.00/man/man4'
        ==> MAKING "all" ON SUBCOMPONENT "SRCROOT/man/man4/makerules.mk"
make[3]: Entering directory `/home/admin/cdrtools-3.00/man/man4'
        ==> LOCALIZING "OBJ/amd-turion-tm--64-mobile-technology-mt-37-linux-gcc/man/makerules.5"
make[3]: Leaving directory `/home/admin/cdrtools-3.00/man/man4'
make[2]: Leaving directory `/home/admin/cdrtools-3.00/man/man4'
make[1]: Leaving directory `/home/admin/cdrtools-3.00/man'
$ 
$ su
# make INS_BASE=/usr/local install
                W A R N I N G   Messages like:

gmake[2]: Entering directory `/tmp/cdrtools-2.01/libschily'
../RULES/r-gmake.dep:76: OBJ//cvmod.d: No such file or directory
../RULES/r-gmake.dep:76: OBJ//dat.d: No such file or directory
../RULES/r-gmake.dep:76: OBJ//fcons.d: No such file or directory
../RULES/r-gmake.dep:76: OBJ//fdown.d: No such file or directory
../RULES/r-gmake.dep:76: OBJ//fdup.d: No such file or directory

〜

make[3]: Entering directory `/home/admin/cdrtools-3.00/man/man4'
        ==> INSTALLING "/usr/local/share/man/man5/makefiles.5"
make[3]: Leaving directory `/home/admin/cdrtools-3.00/man/man4'
        ==> MAKING "install" ON SUBCOMPONENT "SRCROOT/man/man4/makerules.mk"
make[3]: Entering directory `/home/admin/cdrtools-3.00/man/man4'
        ==> INSTALLING "/usr/local/share/man/man5/makerules.5"
make[3]: Leaving directory `/home/admin/cdrtools-3.00/man/man4'
make[2]: Leaving directory `/home/admin/cdrtools-3.00/man/man4'
make[1]: Leaving directory `/home/admin/cdrtools-3.00/man'
#
 

目的のツールである cdrecord に加えて
音楽抽出ツールである cdda2mp3 cdda2ogg cdda2wav
ISOイメージを作成するための mkhybrid mkisofs などもインストールされます

使い方

cdrecord -scanbus で デバイス一覧を表示できます
以降の操作は root権限が必要です

(cdrtools-2.01 の場合)

# cdrecord -scanbus
Cdrecord-Clone 2.01 (i686-pc-linux-gnu) Copyright (C) 1995-2004 Jg Schilling
cdrecord: Warning: Running on Linux-2.6.24
cdrecord: There are unsettled issues with Linux-2.5 and newer.
cdrecord: If you have unexpected problems, please try Linux-2.4 or Solaris.
Linux sg driver version: 3.5.34
Using libscg version 'schily-0.8'.
scsibus0:
        0,0,0     0) *
        0,1,0     1) *
        0,2,0     2) *
        0,3,0     3) *
        0,4,0     4) *
        0,5,0     5) 'IOMEGA  ' 'ZIP 100         ' 'C.18' Removable Disk
        0,6,0     6) 'EPSON   ' 'SCANNER GT-7600 ' '1.03' Processor
        0,7,0     7) *
scsibus1:
        1,0,0   100) 'Multi   ' 'Flash Reader    ' '1.00' Removable Disk
        1,1,0   101) *
        1,2,0   102) *
        1,3,0   103) *
        1,4,0   104) *
        1,5,0   105) *
        1,6,0   106) *
        1,7,0   107) *
#
 

装置は全て SCSIの管理方法に従い「バス番号,SCSI番号,論理番号」で識別されます
bus0 は (本当の)SCSIの装置が認識されています (今なお ZIPドライブを使ってます!!)
bus1 は USBの装置が認識されています
で肝心の ATAバスが見えてきません ATAをスキャンすることを明示する必要があります

# cdrecord -scanbus dev=ATA
Cdrecord-Clone 2.01 (i686-pc-linux-gnu) Copyright (C) 1995-2004 Jg Schilling
cdrecord: Warning: Running on Linux-2.6.24
cdrecord: There are unsettled issues with Linux-2.5 and newer.
cdrecord: If you have unexpected problems, please try Linux-2.4 or Solaris.
scsidev: 'ATA'
devname: 'ATA'
scsibus: -2 target: -2 lun: -2
Warning: Using badly designed ATAPI via /dev/hd* or /dev/cdroms/cdrom* interface.
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.8'.
scsibus2:
        2,0,0   200) '_NEC    ' 'DVD_RW ND-2510A ' '2.18' Removable CD-ROM
        2,1,0   201) *
        2,2,0   202) *
        2,3,0   203) *
        2,4,0   204) *
        2,5,0   205) *
        2,6,0   206) *
        2,7,0   207) *

見えました bus2 が ATA→SCSIエミュレーション です
cdrtoolsでは SCSI(エミュレーション込み)デバイスを扱うため libscg 経由で装置にアクセスします

(cdrtools-3.00 の場合)

# cdrecord -scanbus
Cdrecord-ProDVD-ProBD-Clone 3.00 (i686-pc-linux-gnu) Copyright (C) 1995-2010 Jrg Schilling
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.9'.
scsibus1001:
        1001,0,0 100100) *
        1001,1,0 100101) 'BENQ    ' 'DVD DC DW1670   ' '102 ' Removable CD-ROM
        1001,2,0 100102) *
        1001,3,0 100103) *
        1001,4,0 100104) *
        1001,5,0 100105) *
        1001,6,0 100106) *
        1001,7,0 100107) *
#
 

Linux-2.6では dev=ATA の指示がなくてもいきなり デバイスが確認できました
そういう意味では Linux-2.6は多少楽になっています

次に CD焼き込み機能を検証してみます

(cdrtools-2.01)
ダウンロードした Ubuntu 8.04 を CDに焼いてみました

# cdrecord dev=ATA:2,0,0 speed=4 ubuntu-ja-8.04-desktop-i386.iso
#
 

パラメータ dev により ATA:2,0,0 と該当CDドライブの識別子を指定して焼くことができました

(cdrtools-3.00)
これもダウンロードした Ubuntu 11.04 を CDに焼いてみました

# cdrecord -overburn dev=1001,1,0 speed=4 ubuntu-ja-11.04-desktop-i386.iso
cdrecord: No write mode specified.
cdrecord: Assuming -sao mode.
cdrecord: If your drive does not accept -sao, try -tao.
cdrecord: Future versions of cdrecord may have different drive dependent defaults.
Cdrecord-ProDVD-ProBD-Clone 3.00 (i686-pc-linux-gnu) Copyright (C) 1995-2010 Jrg Schilling
scsidev: '1001,1,0'
scsibus: 1001 target: 1 lun: 0
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.9'.
Device type    : Removable CD-ROM
Version        : 0
Response Format: 2
Capabilities   : 
Vendor_info    : 'BENQ    '
Identifikation : 'DVD DC DW1670   '
Revision       : '102 '
Device seems to be: Generic mmc2 DVD-R/DVD-RW/DVD-RAM.
Using generic SCSI-3/mmc   CD-R/CD-RW driver (mmc_cdr).
Driver flags   : MMC-3 SWABAUDIO BURNFREE 
Supported modes: TAO PACKET SAO SAO/R96P SAO/R96R RAW/R16 RAW/R96P RAW/R96R
cdrecord: Warning: Cannot read drive buffer.
cdrecord: Warning: The DMA speed test has been skipped.
cdrecord: WARNING: Data may not fit on current disk.
cdrecord: Notice: Overburning active. Trying to write more than the official disk capacity.
Starting to write CD/DVD/BD at speed 8 in real SAO mode for single session.
Last chance to quit, starting real write    0 seconds. Operation starts.
Turning BURN-Free off
cdrecord: WARNING: Drive returns wrong startsec (0) using -150

cdrecord: Success. write_g1: scsi sendcmd: no error
CDB:  2A 00 00 05 44 BE 00 00 1F 00
status: 0x2 (CHECK CONDITION)
Sense Bytes: 70 00 03 00 00 00 00 0A 00 00 58 00 0C 00 00 00
Sense Key: 0x3 Medium Error, Segment 0
Sense Code: 0x0C Qual 0x00 (write error) Fru 0x0
Sense flags: Blk 0 (not valid) 
resid: 63488
cmd finished after 0.088s timeout 200s
write track data: error after 707129344 bytes
cdrecord: A write error occured.
cdrecord: Please properly read the error message above.
#
 

-overburn を付けないとWARNINGの後焼き込みがキャンセルされたため -overburn を付けてます
またメッセージをよく見るとエラーが出ているようですが 書き込み自体は成功してました

# mount -t iso9660 -o ro /dev/cdroms/cdrom3 /mnt/cdrom
# ls /mnt/cdrom/
README.diskdefines  boot    dists    isolinux    pics  preseed  usb-creator.exe
autorun.inf         casper  install  md5sum.txt  pool  ubuntu   wubi.exe
#
 

次に音楽CDからの音楽データ取り込みを試してみます
cdrtoolsパッケージに含まれる 有名ツール cdda2wav を利用します
今回は 音楽データをwavファイルに抽出した上で lameというエンコーダを使って MP3にエンコードします

(cdrtools-2.01)
今回 実験に使った音楽CDはこれ 水樹奈々「MASSIVE WONDERS」
MASSIVE WONDERS 水樹奈々
1トラック目の MASSIVE WONDERS を MP3化しました
まず CDから wavファイルを抽出します

# cdda2wav -c 2 -b 16 -r 44100 -t 1 dev=/dev/cdroms/cdrom0 nana1.wav
cdrom device (/dev/cdroms/cdrom0) is not of type generic SCSI. Setting interface to cooked_ioctl.
126976 bytes buffer memory requested, 4 buffers, 8 sectors
#Cdda2wav version 2.01_linux_2.6.24_i686_amd-turion-tm--64-mobile-technology-mt-37, real time sched., soundcard, libparanoia support
EnableCdda_cooked (CDIOCSETCDDA) is not available...
AUDIOtrack pre-emphasis  copy-permitted tracktype channels
      1- 6          yes              no     audio    2
Table of Contents: total tracks:6, (total time 25:28.52)
  1.( 4:15.60),  2.( 3:59.66),  3.( 4:29.54),  4.( 4:15.52),  5.( 3:59.67),
  6.( 4:27.53)

Table of Contents: starting sectors
  1.(       0),  2.(   19185),  3.(   37176),  4.(   57405),  5.(   76582),
  6.(   94574), lead-out(  114652)
CDINDEX discid: LSkw6kvvwWsz_JcKoghzMslMsXI-
CDDB discid: 0x4905f806
CD-Text: not detected
CD-Extra: not detected
samplefile size will be 45123164 bytes.
recording 255.8000 seconds stereo with 16 bits @ 44100.0 Hz ->'nana1'...
cdda2wav: Operation not permitted. cannot set posix realtime scheduling policy
overlap:min/max/cur, jitter, percent_done:
 0/ 0/ 1/      0  99%EnableCdda_cooked (CDIOCSETCDDA) is not available...
 0/ 0/ 1/      0 100%  track  1 recorded successfully
#
 

オプションの説明は
-c 2 2ch つまりステレオオーディオで記録します
-b 16 16bits/sample の情報量の指定です
-r 44100 44.1kbpsのサンプリングレートです
dev= オーディオデバイス(CDROM)を指定します

続いて吸い出した音楽ファイルを MP3化します
lameというコマンドを使います (lameについては後述します)

$ lame nana1.wav nana1.mp3
LAME 3.98 32bits (http://www.mp3dev.org/)
Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz
Encoding nana1.wav to /home/admin/nana1.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (11x) 128 kbps qval=3
    Frame          |  CPU time/estim | REAL time/estim | play/CPU |    ETA 
  9794/9794  (100%)|    0:17/    0:17|    0:18/    0:18|   14.277x|    0:00 
-------------------------------------------------------------------------------
   kbps        LR    MS  %     long switch short %
  128.0        2.6  97.4        97.3   1.6   1.0
Writing LAME Tag...done
ReplayGain: -11.9dB

うまくいきました
lameはオプションを指定しないと Joint Stereo VBR(可変ビットレート) でエンコードするようです

(cdrtools-3.00)
実験材料は 水樹奈々「ULTIMATE DIAMOND」
ULTIMATE DIAMOND 水樹奈々
1トラック目の MARIA&JOKER を MP3化しました

# cdda2wav -c 2 -b 16 -r 44100 -t 1 dev=/dev/cdroms/cdrom3 nana1.wav
Type: ROM, Vendor 'BENQ    ' Model 'DVD DC DW1670   ' Revision '102 ' MMC+CDDA
569344 bytes buffer memory requested, transfer size 131072 bytes, 4 buffers, 55 sectors
#Cdda2wav version 3.00_linux_2.6.30.5_i686_amd-turion-tm--64-mobile-technology-mt-37, real time sched., soundcard, libparanoia support
AUDIOtrack pre-emphasis  copy-permitted tracktype channels
      1-15           no              no     audio    2
Table of Contents: total tracks:15, (total time 65:26.48)
  1.( 4:12.50),  2.( 3:49.05),  3.( 3:23.12),  4.( 3:47.43),  5.( 4:33.45),
  6.( 3:52.45),  7.( 4:34.17),  8.( 4:42.03),  9.( 4:22.62), 10.( 4:32.48),
 11.( 4:22.32), 12.( 4:55.72), 13.( 4:27.68), 14.( 4:33.50), 15.( 5:16.21),

Table of Contents: starting sectors
  1.(       0),  2.(   18950),  3.(   36130),  4.(   51367),  5.(   68435),
  6.(   88955),  7.(  106400),  8.(  126967),  9.(  148120), 10.(  167832),
 11.(  188280), 12.(  207962), 13.(  230159), 14.(  250252), 15.(  270777),
 lead-out(  294498)
CDINDEX discid: xOn5Dfd3A1SKoSj99X4zGA4GaEs-
CDDB discid: 0xd70f560f
CD-Text: not detected
CD-Extra: not detected
samplefile size will be 44570444 bytes.
recording 252.6666 seconds stereo with 16 bits @ 44100.0 Hz ->'nana1'...
percent_done:
100%  track  1 recorded successfully
# 
 

続いて MP3化します

$ lame nana1.wav nana1.mp3
LAME 3.98 32bits (http://www.mp3dev.org/)
Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz
Encoding nana1.wav to nana1.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (11x) 128 kbps qval=3
    Frame          |  CPU time/estim | REAL time/estim | play/CPU |    ETA 
  9674/9674  (100%)|    0:17/    0:17|    0:18/    0:18|   14.408x|    0:00 
-------------------------------------------------------------------------------
   kbps        LR    MS  %     long switch short %
  128.0        2.2  97.8        98.3   0.9   0.7
Writing LAME Tag...done
ReplayGain: -10.4dB
$
 

以上です 特に両バージョンとも同じように動作しました

今回 cdrtools-2.01(2008年) cdrtools-3.00(2011年) 両バージョンで並行記述しましたが
偶然なのかやっている活動自体が Ubuntu焼く 水樹奈々MP3化 と3年経っても変わり映えしない
ところが 我ながらすごいとか思いました…

lameとは

Lame Ain’t an Mp3 Encoder の略で
MP3エンコーダでないとか書かれてますが 高品質MP3エンコーダです
他にも 午後のこ〜だというものがありますが 高速低品質です
ここからソースコードをダウンロードして 次のようにインストールします

$ tar -xzf lame-398.tar.gz
$ cd lame-398
$ ./configure --prefix=/usr/local
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a BSD-compatible install... /bin/install -c
〜
config.status: creating macosx/Makefile
config.status: creating macosx/English.lproj/Makefile
config.status: creating macosx/LAME.xcodeproj/Makefile
config.status: creating config.h
config.status: executing depfiles commands
$ make
make  all-recursive
make[1]: Entering directory `/home/admin/lame-398'
Making all in mpglib
make[2]: Entering directory `/home/admin/lame-398/mpglib'
〜
make[3]: `all-am' に対して行うべき事はありません。
make[3]: Leaving directory `/home/admin/lame-398/macosx'
make[2]: Leaving directory `/home/admin/lame-398/macosx'
make[2]: Entering directory `/home/admin/lame-398'
make[2]: `all-am' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/lame-398'
make[1]: Leaving directory `/home/admin/lame-398'
$ su
# make install
Making install in mpglib
make[1]: Entering directory `/home/admin/lame-398/mpglib'
make[2]: Entering directory `/home/admin/lame-398/mpglib'
make[2]: `install-exec-am' に対して行うべき事はありません。
〜
make[2]: `install-exec-am' に対して行うべき事はありません。
make[2]: `install-data-am' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/lame-398'
make[1]: Leaving directory `/home/admin/lame-398'
#
 

これにより lame というコマンドが使えるようになります

GV-MVP/RX2(ハードウェアMPEG2エンコード+TVチューナ付 キャプチャボード) で動画を見る

GV-MVP/RX2 のインストール

GV-MVP/RX2 を入手したので Linuxでの導入の流れをレポートします
(2008年 Linux-2.6.24, 2011年 Linux-3.0, 2013年 Linux-3.7.8 で検証しました)

Linuxで ハードウェアエンコード可能な TVキャプチャボードは数が限られていて
この GV-MVP/RX2 もその数少ない1つ

GV-MVP/RX2
画像は 別のHPのを拾ってきた物なので注意 モノはもう中古ショップかオークションでしか手に入りません

GV-MVP/RX2 の構成
名称 GV-MVP/RX2 (生産終了)
MPEG2エンコーダ CONEXANT CX23416-12
デコーダ Philips SAA7173HL
Y/C分離 NEC uPD64084
ゴーストリデューサ NEC uPD64031
チューナ Panasonic VP27S/ENGE4324D
音声 XWM8739 (I2Sバス)
ADコンバータ KHTEK AD1180

GV-MVP/RX と同等の構成のようです また GV-MVP/RX2E は Y/C分離やゴーストリデューサの機能が外れた簡易版のようです
これらの構成チップが システム上で認識されるようにドライバモジュールを準備する必要があります

また 2011年以降の 64bit環境では
すでに アナログTV放送が終了してしまっているので チューナの正常動作を確認していません
S-VIDEO + 音声端子入力 の正常動作確認のみです

参考になる情報サイトとしては ぱ研ここFedora関係のページ

マシン構成
2008年 Linux-2.6.24
CPU Turion(tm)64-MT37 2.0GHz
マザーボード KV8 Pro 3rd Eye
グラフィック GeForce6600GT
OS Linux kernel-2.6.24 (32bit)
GCC 4.1.2
glibc 2.5
2011年 Linux-3.0
CPU PhenomII X4 905e 2.5GHz 4コア
マザーボード GA-880GM-USB3
グラフィック Radeon HD 4250 オンボード
OS Linux kernel-3.0 (64bit)
GCC 4.5.2
glibc 2.13
2013年 Linux-3.7.8
CPU PhenomII X4 905e 2.5GHz 4コア
マザーボード GA-880GM-USB3
グラフィック Radeon HD 4250 オンボード
OS Linux kernel-3.7.8 (64bit)
GCC 4.5.2
glibc 2.13

カーネルのコンパイル

先に Linuxカーネルとして必要なモジュールを掲載しておきます 下記の表を参照ください

カーネルコンフィグ (Linux-2.6.24)
i2c-core 「I2C support」カーネルに組込めばOK
i2c-dev 「I2C device interface」カーネルに組込めばOK
i2c-algo-bit 「I2C bit-banging interfaces」カーネルに組込めばOK
videodev 「Video For Linux」カーネルに組込む CONFIG_VIDEO_V4L2 も自動で設定される
v4l1-compat 「Enable Video For Linux API 1 (DEPRECATED)」 と 「Enable Video For Linux API 1 compatible Layer」 をカーネルに組込み
ivtv, cx2341x 「Video capture adapters」を組み込んだ上で 「Conexant cx23416/cx23415 MPEG encoder/decoder support」をモジュールとしてビルドする ivtv.koモジュールが作られる
ちなみに ivtvfb は不要 (GV-MVP/RX2以外のチューナ用?)
tuner_simple 「Customize analog tuner modules to build」した上で 「Simple tuner support」のみをカーネルに組込み (Customize〜 を選択しない方法もあり 全てチューナモジュールがモジュール生成されるがそれはそれで動作する)
upd64031a 「Autoselect pertinent encoders/decoders and other helper chips」を外した上で 「Encoders/decoders and other helper chips」の 「NEC Electronics uPD64031A Ghost Reduction」 をモジュール組込む
upd64083 「Autoselect pertinent encoders/decoders and other helper chips」を外した上で 「Encoders/decoders and other helper chips」の 「NEC Electronics uPD64083 3-Dimensional Y/C separation」 をモジュールとしてビルドする
カーネルコンフィグ (Linux-3.0 差分)
rc_core ivtvモジュールに必要 「Device Drivers」→「Multimedia support」→「Remote Controller adapters」をカーネルに組込めばOK
カーネルコンフィグ (Linux-3.7.8 差分)
MEDIA_ANALOG_TV_SUPPORT もしくは
MEDIA_DIGITAL_TV_SUPPORT
「Device Drivers」→「Multimedia support」を有効にした上で 「Analog TV support」もしくは「Digital TV support」を指定
VIDEO_IVTV 「Media PCI Adapters」→「Conexant cx23416/cx23415 MPEG encoder/decoder support」を選択する まったく別の「Conexant CX2341x MPEG encoders」という項目がありこちらは全く動かないので注意
VIDEO_UPD64031A 「Encoders, decoders, sensors and other helper chips」→「NEC Electronics uPD64031A Ghost Reduction」が選択されていることを確認 ゴースト低減モジュール
VIDEO_UPD64083 「Encoders, decoders, sensors and other helper chips」→「NEC Electronics uPD64083 3-Dimensional Y/C separation」が選択されていることを確認 3次元Y/C分離モジュール

具体的にカーネルコンフィグ(make menuconfig)を キャプチャイメージで紹介します
まず Linux-2.6.24 から
I2C support
「I2C support」に *チェックをいれた上で 「I2C device interface」にも *チェック入れます
I2C Algorithms
「I2C Algorithms」では 「I2C bit-banging interfaces」にチェックをいれます
M 指定して i2c_algo_bit モジュールとして作ってもかまいません
Multimedia devices
「Video For Linux」「Enable Video For Linux API 1」「同 compatible Layer」をチェックし
「customize analog tuner modules to build」のチェックを外しておけば
tuner モジュールをいれた場合に適切な チューナ用モジュールを選択してくれるようです
(customize analog tuner modules にチェックを入れて 不要なチューナを省略指定できるかも)
また 「Video capture adapters」を *選択したうえで次に
Video capture adapters
「Conexant cx23416/cx23415 MPEG encoder/decoder support」(ivtv)を M モジュール化します
カーネルで ivtv.ko モジュールを作らせてインストールしておいて
後で 外部の ivtv.ko で置き換えるという方針です

次に Linux-3.0 でのカーネルコンフィグです
I2C support
まず 「Device Drivers」→「I2C support」を組込みにします
I2C supportのサブメニューは 上記のようにしました
Multimedia support
「Device Drivers」→「Multimedia support」の中で必要なのは
「Video For Linux」「Remote Controller adapters」「Video capture adapters」です

Remote Controller adapters のサブメニューでは
各メーカーの赤外線プロトコルがデフォルトで組み込まれていますが 不要なので解除して構いません
Video capture adapters
Video capture adapters もサブメニューになっています
ここでは GV-MVP/RX2のモジュールとなる ivtv.ko を作るために
「Conexant cx23416/cx23415 MPEG encoder/decoder support」をモジュール選択します
Linux-2.6.24のときとは異なり カーネル付属のドライバで動作したため
後から ivtv.ko を差し替える必要はありません 従ってモジュールでなく組込みでも構いません

さらに 「Autoselect pertinent encoders/decoders and other helper chips」を
組込みにすることで チューナやデコーダなど幾つかサブモジュールを自動選択してくれるようです
(GV-MVP/RX2の場合 Conexant cx23416/cx23415 を選択した時点で
自動的に必要なサブモジュールを選択済にしてくれます)

最後に ファームウェアの対応として (ファームウェアについては後述します)
Generic Driver Options
「Device Drivers」→「Generic Driver Options」で
「path to uevent helper」を /sbin/hotplug に設定します

次に Linux-3.7.8 でのカーネルコンフィグです
I2C support
I2Cの基本機能は必須です
Analog TV support
キャプチャでは Analog TV support / Digital TV support 両方有効にしてますが
Analog TV supportのみでもいけるはずです
Conexant cx23416/cx23415 MPEG encoder/decoder support
Analog TV supportを選択していないと この選択肢が見えてこないので注意

上記のコンフィグでカーネルをビルド
モジュールもインストール(make modules_install)し再起動しましょう
ファームウェアをまだ入れてないので この時点では下記のようにエラーとなるはずです
(Linux-2.6.24の場合)

$ lsmod
Module                  Size  Used by
nvidia               4702512  22 
 

この時点でまだ ビデオキャプチャ系のモジュールは見えません

$ dmesg
〜
i2c /dev entries driver
〜
 

I2Cドライバは モジュール化せずに組み込んだので ブート時に認識されています

しかしここで ivtvモジュールをロード(insmod)すると しばらく固まったあと
dmesg出力に下記のエラーが表示され ファームウェアのロードに失敗したことが分かります

fw_setup_device() : name=v4l-cx2341x-enc.fw uevent=1 return=0<3>ivtv0: Unable to open firmware v4l-cx2341x-enc.fw (must be 376836 bytes)
ivtv0: Did you put the firmware in the hotplug firmware directory?
ivtv0: Retry loading firmware
fw_setup_device() : name=v4l-cx2341x-enc.fw uevent=1 return=0<3>ivtv0: Unable to open firmware v4l-cx2341x-enc.fw (must be 376836 bytes)
ivtv0: Did you put the firmware in the hotplug firmware directory?
ivtv0: Failed to initialize on minor 0
 

(Linux-3.0の場合)
同様に dmesgでエラーメッセージが確認できます

ivtv: Start initialization, version 1.4.2
ivtv0: Initializing card 0
ivtv0: Autodetected I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) card (cx23416 based)
ivtv 0000:04:07.0: PCI INT A -> GSI 21 (level, low) -> IRQ 21
ivtv0: Unreasonably low latency timer, setting to 64 (was 32)
saa7115 1-0021: saa7115 found (1f7115d0e100000) @ 0x42 (ivtv i2c driver #0)
i2c-core: driver [tuner] using legacy suspend method
i2c-core: driver [tuner] using legacy resume method
tda9887 1-0043: creating new instance
tda9887 1-0043: tda988[5/6/7] found
tuner 1-0043: Tuner 74 found with type(s) Radio TV.
All bytes are equal. It is not a TEA5767
tuner 1-0060: Tuner -1 found with type(s) Radio TV.
upd64031a 1-0012: chip found @ 0x24 (ivtv i2c driver #0)
upd64083 1-005c: chip found @ 0xb8 (ivtv i2c driver #0)
wm8739 1-001a: chip found @ 0x34 (ivtv i2c driver #0)
vp27smpx 1-005b: chip found @ 0xb6 (ivtv i2c driver #0)
tuner-simple 1-0060: creating new instance
tuner-simple 1-0060: type set to 46 (Panasonic VP27s/ENGE4324D)
ivtv0: Registered device video0 for encoder MPG (4096 kB)
ivtv0: Registered device video32 for encoder YUV (2048 kB)
ivtv0: Registered device vbi0 for encoder VBI (1024 kB)
ivtv0: Registered device video24 for encoder PCM (320 kB)
ivtv0: Initialized card: I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)
ivtv: End initialization
ivtv0: Unable to open firmware v4l-cx2341x-enc.fw (must be 376836 bytes)
ivtv0: Did you put the firmware in the hotplug firmware directory?
ivtv0: Retry loading firmware
ivtv0: Unable to open firmware v4l-cx2341x-enc.fw (must be 376836 bytes)
ivtv0: Did you put the firmware in the hotplug firmware directory?
ivtv0: Failed to initialize on device video32
ivtv0: Failed to initialize on device vbi0
ivtv0: Failed to initialize on device video24
ivtv0: Failed to initialize on device video0
 

Linux-3.0では GV-MVP/RX2のカードが認識され 各種サブモジュールも初期化されています
ただし最後の方で v4l-cx2341x-enc.fw が見付からずカード初期化に失敗しています
これは カーネルコンフィグで設定した ueventヘルパがファームウェアロードに失敗しているためです

ファームウェアは見付からないものの ここまででカーネルのコンフィグは完了です

ファームウェアのインストール

実際のところ カーネルコンフィグよりもこちらの方が苦労しました
ファームウェアのインストール方法です

まずファームウェアのイメージを用意します
IVTVプロジェクトの firmware.tar.gz を使いました(ドライバCDから抽出する方法もあるらしい)

$ su
# mkdir /lib/firmware
# cd /lib/firmware
# tar -xzf ~admin/firmware.tar.gz
# ls -l
合計 824
-rw-r--r--  1 505 502 262144  5月 26  2006 v4l-cx2341x-dec.fw
-rw-r--r--  1 505 502 376836  2月 17  2007 v4l-cx2341x-enc.fw
-rw-r--r--  1 505 502 155648  5月 26  2006 v4l-cx2341x-init.mpg
-rw-r--r--  1 505 502  16382  5月 26  2006 v4l-cx25840.fw
-rw-r--r--  1 505 502   8192 10月  6  2006 v4l-pvrusb2-24xxx-01.fw
-rw-r--r--  1 505 502   8192  7月  1  2006 v4l-pvrusb2-29xxx-01.fw
#
 

実際に使われるのは v4l-cx2341x-dec.fw v4l-cx2341x-enc.fw くらいだと思います
検証の環境では /lib/firmware/ に配置しましたが
ディストリビューションによっては /usr/lib/hotplug/firmware/ などに配置する例もあります

以上でイメージは準備できました

では ファームウェアをロードする仕組みと環境構築方法について説明します
ivtvドライバ動作としてはファームウェアを要求するのに request_firmware() が使われます

(Linux-2.6.24の場合)
2007年くらいの Linuxでは
HOTPLUG と sysfs の機能により request_firmware() が処理されます
まず hotplug の確認から

$ cat /proc/sys/kernel/hotplug
/sbin/hotplug
 

カーネルの機能により /sbin/hotplug スクリプトが読み込まれる設定となっています
実際の hotplugスクリプトの内容は以下のとおりです

$ cat /sbin/hotplug
〜
DIR="/etc/hotplug.d"

# echo '/sbin/hotplug debug: ' $1 >> /ram/hotpluglog

for I in "${DIR}/$1/"*.hotplug "${DIR}/"default/*.hotplug ; do
        if [ -f $I ]; then
                test -x $I && $I $1 ;
        fi
done

exit 1
 

数行のシェルスクリプトで /etc/hotplug.d/引数/*.hotplug のスクリプトを呼び出す仕様
であることがわかります ちなみに 引数は 「firmware」 が指定されるようです

対応して /etc/hotplug.d/firmware/firmware.hotplug (755) を以下の内容で記述します

#!/bin/sh
#
# Firmware-specific hotplug policy agent.
#
# Kernel firmware hotplug params include:
#
#       ACTION=%s [add or remove]
#       DEVPATH=%s [in 2.5 kernels, /sys/$DEVPATH]
#       FIRMWARE=%s
#
# HISTORY:
#
# 24-Jul-2003   Initial version of "new" hotplug agent.
#
# $Id: firmware.agent,v 1.1 2003/10/07 19:34:19 kroah Exp $
#

cd /etc/hotplug
. hotplug.functions
# DEBUG=yes export DEBUG

# directory of the firmware files
FIRMWARE_DIR=/lib/firmware

# mountpoint of sysfs
SYSFS=$(sed -n 's/^.* \([^ ]*\) sysfs .*$/\1/p' /proc/mounts)

# use /proc for 2.4 kernels
if [ "$SYSFS" = "" ]; then
    SYSFS=/proc
fi

#
# What to do with this firmware hotplug event?
#
# new code
echo "ECHOING DEVICE PATH";
echo $DEVPATH;
echo $ACTION;
echo $SYSFS;
echo $FIRMWARE;

case "$ACTION" in

add)
    if [ ! -e $SYSFS/$DEVPATH/loading ]; then
        sleep 1
    fi

    if [ -f $FIRMWARE_DIR/$FIRMWARE ]; then
        echo 1 > $SYSFS/$DEVPATH/loading
        cp $FIRMWARE_DIR/$FIRMWARE $SYSFS/$DEVPATH/data
        echo 0 > $SYSFS/$DEVPATH/loading
    else
        echo -1 > $SYSFS/$DEVPATH/loading
    fi

    ;;

remove)
    ;;

*)
    mesg "Firmware '$ACTION' event not supported"
    exit 1
    ;;

esac
 

ちなみに このスクリプトは どっかのホームページからのパクリです
hotplugが呼び出されるときに $DEVPATH $ACTION $SYSFS $FIRMWARE の環境変数がセットされるようでそれを組み合わせて適切なファームウェアを /sys/〜/data にアップロードする仕組みです

では ここまでで作成したカーネルモジュールを実際にロードしてみます
関連するチップのモジュールをロードしてから ivtvモジュールをロードします
tuner=46 と ntsc=j のオプション指定は必須です

$ su
# modprobe saa7115
# modprobe upd64031a
# modprobe upd64083
# modprobe wm8739
# modprobe cx2341x
# modprobe tuner
# modprobe ivtv tuner=46 ntsc=j
# chmod 666 /dev/video0
# exit
 

一般ユーザでも video0 にアクセスできるように アクセス権限を設定しています
モジュールとしては以下のように見えます

$ lsmod
Module                  Size  Used by
ivtv                  114752  0 
tveeprom               13328  1 ivtv
tuner                  36768  0 
tea5767                 4804  1 tuner
tda8290                10116  1 tuner
tuner_simple            7048  1 tuner
mt20xx                 10760  1 tuner
tea5761                 4036  1 tuner
cx2341x                10052  1 ivtv
wm8739                  5520  0 
upd64083                4688  0 
upd64031a               4944  0 
saa7115                13392  0 
nvidia               4702512  22 
 

tunerのサブモジュールが複数読み込まれているのが見えます(使われているかどうかわかりませんが)
tveepromは tuner用の EEPROM処理モジュールです

$ dmesg
ivtv:  Start initialization, version 1.1.0
ivtv0: Initializing card #0
ivtv0: Autodetected I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) card (cx23416 based)
ACPI: PCI Interrupt 0000:00:0b.0[A] -> GSI 19 (level, low) -> IRQ 21
ivtv0: Unreasonably low latency timer, setting to 64 (was 32)
saa7115 3-0021: saa7115 found (1f7115d0e100000) @ 0x42 (ivtv i2c driver #0)
upd64031a 3-0012: chip found @ 0x24 (ivtv i2c driver #0)
upd64083 3-005c: chip found @ 0xb8 (ivtv i2c driver #0)
wm8739 3-001a: chip found @ 0x34 (ivtv i2c driver #0)
tuner 3-0043: chip found @ 0x86 (ivtv i2c driver #0)
tda9887 3-0043: tda988[5/6/7] found @ 0x43 (tuner)
tuner 3-0043: type set to tda9887
All bytes are equal. It is not a TEA5767
tuner 3-0060: chip found @ 0xc0 (ivtv i2c driver #0)
ivtv0: Failed to load module tuner
ivtv0: Failed to load module saa7115
ivtv0: Failed to load module upd64031a
ivtv0: Failed to load module upd64083
ivtv0: Failed to load module vp27smpx
ivtv0: Failed to load module wm8739
tuner-simple 3-0060: type set to 46 (Panasonic VP27s/ENGE4324D)
tuner 3-0060: type set to Panasonic VP27s/ENG
ivtv0: Registered device video0 for encoder MPG (4096 kB)
ivtv0: Registered device video32 for encoder YUV (2048 kB)
ivtv0: Registered device vbi0 for encoder VBI (1024 kB)
ivtv0: Registered device video24 for encoder PCM (320 kB)
ivtv0: Initialized card #0: I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)
ivtv:  End initialization
 

ivtvモジュールをロードした瞬間に dmesg的に 各種チップが認識されます
デバイスの初期化まで完了し /dev/ 以下に次のファイルが作られます

$ ls -l /dev/
〜
crw-rw----  1 root root 89,   0  3月 25 22:36 i2c-0
crw-rw----  1 root root 89,   1  3月 25 22:36 i2c-1
crw-rw----  1 root root 89,   2  3月 25 22:36 i2c-2
crw-rw----  1 root root 89,   3  3月 25 23:06 i2c-3
〜
crw-rw----  1 root root 81, 224  3月 25 23:06 vbi0
crw-rw-rw-  1 root root 81,   0  3月 25 23:06 video0
crw-rw-rw-  1 root root 81,  24  3月 25 23:06 video24
crw-rw-rw-  1 root root 81,  32  3月 25 23:06 video32
〜
 

udevの設定で アクセス権の許可を与える設定にしているので
パーミッションの見えかたが多少異なるかもしれません
i2c-0 〜 i2c-3 は I2Cアダプタを表します
vbi0 は VBI(アナログ放送の垂直帰線期間中に埋め込まれるデータで テレテキストとか言われる)
video0 は エンコード済のデータ(この場合 MPEG2)
video24 は PCMサウンドのようです(未確認)
video32 は 非圧縮YUVデータのようです(未確認)

(Linux-3.0以降の場合)
2011年頃のLinuxでは

$ cat /proc/sys/kernel/hotplug

$
 

既に hotplugが無効化されています
カーネルコンフィグのところで設定したように ueventヘルパ という形で
/sbin/hotplug を呼び出す仕組みとなっています

2011年時点では netlinkというデバイス能動監視の仕組みが使われていて
ueventヘルパ を使うケースは推奨されていません
さらに (2010年提供の Gentooイメージでは) /sbin/hotplug /etc/hotplug.d/ もありません

ivtvドライバが request_firmware() を使っている以上
/sbin/hotplug スクリプトを用意する必要があります
この辺りの動作や 下記の対処方法は カーネル付属のドキュメント
Documentation/firmware_class/README に記載されています

下記のように /sbin/hotplug (root) 0755 を作成しましょう

# Both $DEVPATH and $FIRMWARE are already provided in the environment.

HOTPLUG_FW_DIR=/lib/firmware/

echo 1 > /sys/$DEVPATH/loading
cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
echo 0 > /sys/$DEVPATH/loading
 

このスクリプトはファームウェアロード専用スクリプトになります
2.6.24版に比べて かなり簡易な内容です /etc/hotplug.d/ 配下を呼び出すこともしません
動作としては /sys/該当ディレクトリ/data にファームイメージをコピーする機能だけです

これでリブート後の dmesgは下記のように

ivtv: Start initialization, version 1.4.2
ivtv0: Initializing card 0
ivtv0: Autodetected I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) card (cx23416 based)
ivtv 0000:04:07.0: PCI INT A -> GSI 21 (level, low) -> IRQ 21
ivtv0: Unreasonably low latency timer, setting to 64 (was 32)
saa7115 1-0021: saa7115 found (1f7115d0e100000) @ 0x42 (ivtv i2c driver #0)
i2c-core: driver [tuner] using legacy suspend method
i2c-core: driver [tuner] using legacy resume method
tda9887 1-0043: creating new instance
tda9887 1-0043: tda988[5/6/7] found
tuner 1-0043: Tuner 74 found with type(s) Radio TV.
All bytes are equal. It is not a TEA5767
tuner 1-0060: Tuner -1 found with type(s) Radio TV.
upd64031a 1-0012: chip found @ 0x24 (ivtv i2c driver #0)
upd64083 1-005c: chip found @ 0xb8 (ivtv i2c driver #0)
wm8739 1-001a: chip found @ 0x34 (ivtv i2c driver #0)
vp27smpx 1-005b: chip found @ 0xb6 (ivtv i2c driver #0)
tuner-simple 1-0060: creating new instance
tuner-simple 1-0060: type set to 46 (Panasonic VP27s/ENGE4324D)
ivtv0: Registered device video0 for encoder MPG (4096 kB)
ivtv0: Registered device video32 for encoder YUV (2048 kB)
ivtv0: Registered device vbi0 for encoder VBI (1024 kB)
ivtv0: Registered device video24 for encoder PCM (320 kB)
ivtv0: Initialized card: I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)
ivtv: End initialization
ivtv0: Loaded v4l-cx2341x-enc.fw firmware (376836 bytes)
ivtv0: Encoder revision: 0x02060039
 

ファームウェアが正常にロードされたメッセージに変わりました

$ lsmod
Module                  Size  Used by
vp27smpx                2278  1 
wm8739                  2892  1 
upd64083                2577  1 
upd64031a               2838  1 
tuner                  13377  2 
saa7115                11966  1 
ivtv                  122790  0 
cx2341x                13774  1 ivtv
tveeprom               12705  1 ivtv
$ ls /dev/v4l/
by-path  vbi0  video0  video24  video32
$
 

ivtvのモジュールと 関連するサブモジュールも自動的に読み込まれています

次に 2013年時点 Linux-3.7.8では
カーネルドキュメントでも「UDEVの仕組みを見直します」な状況で
まだまだ ホットプラグ関連の仕様は流動的なようですが

ivtv0: Loaded v4l-cx2341x-enc.fw firmware (376836 bytes)
pt1_thread run
ivtv0: Encoder revision: 0x02060039
tuner 0-0043: Tuner has no way to set tv freq
tuner 0-0043: Tuner has no way to set tv freq
v4l_id (2742) used greatest stack depth: 3624 bytes left
 

Linux-3.0 と同じ仕組みで ファームウェアは正常にロードされています
TVチューナが正常に動作していませんが
これは カーネルのコンフィグの段階で不要な選択肢として除外しているためです

ivtvパッケージの導入

カーネルとファームウェアの設定後は IVTVプロジェクト より録画関連ツールを取得します

(Linux-2.6.24の場合)
ivtv-1.0.3.tar.gz を使います
Linux-2.6.24の場合 録画ツールを作成する以外にも
ivtv.ko を Linuxカーネルのものから置き換える重要な目的があります
またこのパッケージでは saa717x.ko モジュールも提供されますがこれは必要ないかもしれません
カーネルに付属の saa7115.ko モジュールで動作しました

ivtv-1.0.3のインストールはおよそ下記の通りです

$ tar -xzf ivtv-1.0.3.tar.gz
$ cd ivtv-1.0.3/
$ tar -xzf f9ivtv33.tar.gz
$ CC=gcc make
make -C driver all
make[1]: Entering directory `/home/admin/ivtv-1.0.3/driver'
created ivtv-svnversion.h
make -C /lib/modules/2.6.24/build M=/home/admin/ivtv-1.0.3/driver modules
make[2]: Entering directory `/usr/src/linux-2.6.24'
  CC [M]  /home/admin/ivtv-1.0.3/driver/ivtv-routing.o
  CC [M]  /home/admin/ivtv-1.0.3/driver/ivtv-cards.o
  CC [M]  /home/admin/ivtv-1.0.3/driver/ivtv-controls.o
  CC [M]  /home/admin/ivtv-1.0.3/driver/ivtv-driver.o
〜
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  vbi.c   -o vbi
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  wss.c   -o wss
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  vbi-passthrough.c   -o vbi-passthrough
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  vbi-detect.c   -o vbi-detect
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  ivtv-pcm-tester.c   -o ivtv-pcm-tester
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  mpeg-read-test.c   -o mpeg-read-test
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  mpeg-freq-test.c   -o mpeg-freq-test
gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  mpeg-read-sleep-test.c   -o mpeg-read-sleep-test
make[1]: Leaving directory `/home/admin/ivtv-1.0.3/test'
$ su
# CC=gcc make install
〜
# exit
$
 

f9ivtv33.tar.gz
かってにLinuxで配布されています
最終的に ivtv.ko が既存のものと置き換わり saa717x.ko モジュールも追加されます
また /usr/local/bin/ 以下に v4l2-ctl ivtvctl ivtv-tune などコマンドが追加されます

(Linux-3.0の場合)
ivtv-utils-1.4.0.tar.gz で動作確認 (S-Videoでの録画) がとれました

  • チューナを利用する TV番組録画は(アナログ放送終了したので)検証していない
  • Linux-2.6.24の時と異なり ivtv.ko モジュールを置き換える必要はありませんでした
  • 同梱の録画用ツール record-v4l2.pl を活用することにしましたが スクリプト修正が必要

では ivtv-utils-1.4.0のインストールの状況は下記の通りです

$ tar -xzf ivtv-utils-1.4.0.tar.gz
$ cd ivtv-utils-1.4.0
$ make CC=gcc
make -C utils all
make[1]: ディレクトリ `/home/admin/ivtv-utils-1.4.0/utils' に入ります
g++ -D_GNU_SOURCE -O2 -Wall -g -I.   -c -o v4l2-ctl.o v4l2-ctl.cpp
In file included from ./linux/videodev2.h:61:0,
                 from v4l2-ctl.cpp:41:
/usr/include/linux/types.h:13:2: 警告: #warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"

〜

In file included from ivtv-fb-16-bit-test.c:10:0:
../utils/linux/ivtvfb.h:35:0: 警告: "FBIO_WAITFORVSYNC" が再定義されました
/usr/include/linux/fb.h:41:0: note: ここが以前の宣言がある位置です
g++ -I../utils -D_GNU_SOURCE -O2 -Wall  -lm  ps-analyzer.cpp   -o ps-analyzer
In file included from ../utils/linux/videodev2.h:61:0,
                 from ps-analyzer.cpp:44:
/usr/include/linux/types.h:13:2: 警告: #warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"
make[1]: ディレクトリ `/home/admin/ivtv-utils-1.4.0/test' から出ます
$
$ find . -type f -perm +1
./utils/ivtv-mpegindex
./utils/ivtvplay
./utils/ivtv-radio
./utils/ivtv-ctl
./utils/v4l2-ctl
./utils/perl/ptune.pl
./utils/perl/record-v4l2.pl
./utils/perl/ptune-ui.pl
./utils/perl/config-editor.pl
./utils/ivtvfwextract.pl
./utils/cx25840ctl/cx25840ctl
./utils/ivtv-tune/ivtv-tune
./test/ps-analyzer
./test/ivtv-fb-16-bit-test
./test/ivtv-fb-colormap-test
./test/ivtv-osd-dma-test
./test/ivtv-yuv-dma-test
./test/mpeg-enc-stop-start-test
./test/mpeg-read-sleep-test
./test/mpeg-freq-test
./test/mpeg-read-test
./test/ivtv-pcm-tester
./test/vbi-detect
./test/vbi-passthrough
./test/wss
./test/vbi
$
 

実行ファイルがいくつか作成されましたが 実際に使いそうな下記ツールのみ手動コピーしました
ivtv-ctl v4l2-ctl record-v4l2.pl ivtv-tune cx25840ctl

$ su
# cp utils/ivtv-ctl /usr/bin/
# cp utils/v4l2-ctl /usr/bin/
# cp utils/perl/record-v4l2.pl /usr/bin/
# cp utils/ivtv-tune/ivtv-tune /usr/bin/
# cp utils/cx25840ctl/cx25840ctl /usr/bin/
# cp utils/cx25840ctl/cx25840ctl.1 /usr/share/man/man1/
#
 

record-v4l2.pl は番組の録画を行うスクリプトです
ただし実際の利用では 下記のコンパイルチェックで Perlモジュールが不足してることが分かります

$ perl -c /usr/bin/record-v4l2.pl
Can't locate Video/Frequencies.pm in @INC (@INC contains: /etc/perl /usr/lib64/perl5/site_perl/5.12.2/x86_64-linux /usr/lib64/perl5/site_perl/5.12.2 /usr/lib64/perl5/vendor_perl/5.12.2/x86_64-linux /usr/lib64/perl5/vendor_perl/5.12.2 /usr/lib64/perl5/5.12.2/x86_64-linux /usr/lib64/perl5/5.12.2 /usr/lib64/perl5/site_perl /usr/lib64/perl5/vendor_perl /usr/local/lib/site_perl .) at /usr/bin/record-v4l2.pl line 115.
BEGIN failed--compilation aborted at /usr/bin/record-v4l2.pl line 115.
$
 

まず Config/IniFiles が必要です これはCPANから取得できます
(インストールの過程は割愛します)
ivtvdriver.org で配布去れている2つのモジュールも導入する必要があります
インストールの過程は 下記の通りです

$ gzip -dv Video-Frequencies-0.03.tar.gz
Video-Frequencies-0.03.tar.gz:    2.8% -- replaced with Video-Frequencies-0.03.tar
$ tar -xf Video-Frequencies-0.03.tar
$ cd Video-Frequencies-0.03
$ perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Video::Frequencies
$ make
cp Frequencies.pm blib/lib/Video/Frequencies.pm
Manifying blib/man3/Video::Frequencies.3pm
$ su
# make install
Installing /usr/lib64/perl5/site_perl/5.12.2/Video/Frequencies.pm
Installing /usr/share/man/man3/Video::Frequencies.3pm
Appending installation info to /usr/lib64/perl5/5.12.2/x86_64-linux/perllocal.pod
# exit
$ cd ..
$ gzip -dv Video-ivtv-0.13.tar.gz
Video-ivtv-0.13.tar.gz:   0.0% -- replaced with Video-ivtv-0.13.tar
$ tar -xf Video-ivtv-0.13.tar
$ cd Video-ivtv-0.13
$ perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Video::ivtv
$ make
cp ivtv.pm blib/lib/Video/ivtv.pm
/usr/bin/perl5.12.2 /usr/lib64/perl5/5.12.2/ExtUtils/xsubpp  -typemap /usr/lib64/perl5/5.12.2/ExtUtils/typemap  ivtv.xs > ivtv.xsc && mv ivtv.xsc ivtv.c
Please specify prototyping behavior for ivtv.xs (see perlxs manual)
gcc -c  -I. -fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -pipe   -DVERSION=\"0.13\" -DXS_VERSION=\"0.13\" -fPIC "-I/usr/lib64/perl5/5.12.2/x86_64-linux/CORE"   ivtv.c
In file included from ivtv.xs:5:0:
/usr/include/linux/types.h:13:2: 警告: #warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"
Running Mkbootstrap for Video::ivtv ()
chmod 644 ivtv.bs
rm -f blib/arch/auto/Video/ivtv/ivtv.so
gcc  -shared -O2 -pipe -Wl,-O1 -Wl,--as-needed ivtv.o  -o blib/arch/auto/Video/ivtv/ivtv.so     \
                \
          
chmod 755 blib/arch/auto/Video/ivtv/ivtv.so
cp ivtv.bs blib/arch/auto/Video/ivtv/ivtv.bs
chmod 644 blib/arch/auto/Video/ivtv/ivtv.bs
Manifying blib/man3/Video::ivtv.3pm
$ su
# make install
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
Installing /usr/lib64/perl5/site_perl/5.12.2/x86_64-linux/auto/Video/ivtv/ivtv.bs
Installing /usr/lib64/perl5/site_perl/5.12.2/x86_64-linux/auto/Video/ivtv/ivtv.so
Installing /usr/lib64/perl5/site_perl/5.12.2/x86_64-linux/Video/ivtv.pm
Installing /usr/share/man/man3/Video::ivtv.3pm
Appending installation info to /usr/lib64/perl5/5.12.2/x86_64-linux/perllocal.pod
#
 

さらに実際に record-v4l2.pl により録画しようとすると
下記のエラーが出たため record-v4l2.pl の修正が必要でした

$ record-v4l2.pl -d /dev/v4l/video0 -I 'S-Video 1' -D /mnt/share/movie --directory-format "" -o test.mpg -t 10
Error calling setEndGOP(1)!
$
 

setEndGOP() や setCodecInfo() が失敗します ioctl() 処理で失敗しているようです
ドライバの問題でしょうか
対処としては 録画データに異常はなかったのでこのエラーを無視するしかありません
record-v4l2.pl を修正しておきます 合計下記4箇所です

1307   if ($ivtvVersion > 265) # > 0.1.9
1308   {
1309     $result = setEndGOP->($tunerFD, $settings{CaptureLastGOP});
1310     if ($result==0)
1311     {
1312 #      die "Error calling setEndGOP($settings{CaptureLastGOP})!\n";
1313     }
1314   }

1329 if ($changedSettings{codec})
1330 {
1331   $result = $ivtvObj->setCodecInfo($tunerFD, @newCodecInfo);
1332   if (!$result)
1333   {
1334 #    die "Error calling setCodecInfo()!\n";
1335   }
1336 }

1355   if ($changedSettings{codec})
1356   {
1357     $result = $ivtvObj->setCodecInfo($tunerFD, @codecInfo);
1358     if (!$result)
1359     {
1360 #      die "Error calling setCodecInfo()!\n";
1361     }
1362   }

1528   # open the file for writing.
1529 
1530   sysopen(OUTPUT, "$fname", O_CREAT | O_TRUNC | O_WRONLY | O_LARGEFILE) or die "Error creating file '$fname': $!\n";
1531 
1532   alarm($RecordDuration);

 

die でプログラムを終了させる箇所をコメントアウトしました 合計3箇所です

最後に録画データの出力時 sysopen() のオプションに O_TRUNC フラグを追加しています
これは同名のファイルに書き込む場合 一旦ファイルを削除する動作とするためです
(これをしないと 動画の最後にごみが残るケースがある)

ひとまず以上で必要なツールがインストールされたことになります
record-v4l2.pl の使い勝手については下記で説明しています

チャンネル選択

先ほどインストールしたツールを使って 各種チャンネルの選択 動画の試聴を試してみます

入力ソースとしては コンポジット入力 S端子入力 TVチューナー のいずれかを選択できます

$ v4l2-ctl -d /dev/video0 -i 2
Video input set to 2 (Composite 1)
 
$ v4l2-ctl -d /dev/video0 -i 1
Video input set to 1 (S-Video 1)
 
$ v4l2-ctl -d /dev/video0 -i 0
Video input set to 0 (Tuner 1)
 

チューナーの場合はさらにチャンネルを選択できます japan-bcaet と japan-cable が選択できます

$ ivtv-tune -d /dev/video0 -t japan-bcast -l
1       91.250
2       97.250
3       103.250
4       171.250
5       177.250
〜
57      735.250
58      741.250
59      747.250
60      753.250
61      759.250
62      765.250
 

アナログ放送周波数の一覧が確認できます

$ ivtv-tune -d /dev/video0 -t japan-cable -l
13      109.250
14      115.250
15      121.250
16      127.250
17      133.250
18      139.250
19      145.250
〜
57      427.250
58      433.250
59      439.250
60      445.250
61      451.250
62      457.250
63      463.250
 

ケーブルテレビの周波数テーブルも同様に確認できます
実際にチャンネルを選択するには -c オプションです

$ ivtv-tune -d /dev/video0 -t japan-bcast -c 12
/dev/video0: 217.250 MHz
 

映像を確認

/dev/video0 は読みだしで MPEG2ストリームとして読み出せます
手元の環境には Xineがインストールされているので それで観賞できます

アナログキャプチャ
japan-bcastのキャプチャ画像です
コンポジットキャプチャ
コンポジット(ストリートファイター3 3rd on Dreamcast)のキャプチャ画像です
実際の映像と 最終的にディスプレイに出力される映像とでは 2秒ほどの遅延があるため
ゲームでの利用は残念ながら現実的ではありません

Xine以外では Xawtvも 試してみましたが
nvidiaドライバ(Depth 24までしか指定できない?)との相性からか
「32bppでないとダメっす」みたいなことを言われて見れませんでした

あと オーバーレイ表示できると低速CPUにとってうれしい状況ですが 確認とれませんでした

画質の調整

実際の ビデオキャプチャの使用についてレポートします

v4l2-ctl コマンドで画質をコントロールできるようです
文法としては v4l2-ctl -d /dev/video0 -c 項目名=値
項目名 とその意味と 値の範囲は以下のコマンドで情報がとれます

$ v4l2-ctl -d /dev/video0 -L

User Controls

                     brightness (int)  : min=0 max=255 step=1 default=128 value=128 flags=slider
                       contrast (int)  : min=0 max=127 step=1 default=64 value=64 flags=slider
                     saturation (int)  : min=0 max=127 step=1 default=64 value=64 flags=slider
                            hue (int)  : min=-128 max=127 step=1 default=0 value=0 flags=slider
                         volume (int)  : min=0 max=65535 step=655 default=58880 value=50736
                        balance (int)  : min=0 max=65535 step=655 default=32768 value=32768
                           mute (bool) : default=1 value=0

MPEG Encoder Controls

                    stream_type (menu) : min=0 max=5 default=0 value=0 flags=update
                                0: MPEG-2 Program Stream
                                2: MPEG-1 System Stream
                                3: MPEG-2 DVD-compatible Stream
                                4: MPEG-1 VCD-compatible Stream
                                5: MPEG-2 SVCD-compatible Stream
              stream_vbi_format (menu) : min=0 max=1 default=0 value=0
                                0: No VBI
                                1: Private packet, IVTV format
       audio_sampling_frequency (menu) : min=0 max=2 default=1 value=1
                                0: 44.1 kHz
                                1: 48 kHz
                                2: 32 kHz
           audio_encoding_layer (menu) : min=1 max=1 default=1 value=1 flags=update
                                1: Layer II
         audio_layer_ii_bitrate (menu) : min=9 max=13 default=10 value=10
                                9: 192 kbps
                                10: 224 kbps
                                11: 256 kbps
                                12: 320 kbps
                                13: 384 kbps
              audio_stereo_mode (menu) : min=0 max=3 default=0 value=0 flags=update
                                0: Stereo
                                1: Joint Stereo
                                2: Dual
                                3: Mono
    audio_stereo_mode_extension (menu) : min=0 max=3 default=0 value=0 flags=inactive
                                0: Bound 4
                                1: Bound 8
                                2: Bound 12
                                3: Bound 16
                 audio_emphasis (menu) : min=0 max=2 default=0 value=0
                                0: No Emphasis
                                1: 50/15 us
                                2: CCITT J17
                      audio_crc (menu) : min=0 max=1 default=0 value=0
                                0: No CRC
                                1: 16-bit CRC
                     audio_mute (bool) : default=0 value=0
                 video_encoding (menu) : min=0 max=1 default=1 value=1 flags=readonly
                                0: MPEG-1
                                1: MPEG-2
                   video_aspect (menu) : min=0 max=3 default=1 value=1
                                0: 1x1
                                1: 4x3
                                2: 16x9
                                3: 2.21x1
                 video_b_frames (int)  : min=0 max=33 step=1 default=2 value=2 flags=update
                 video_gop_size (int)  : min=1 max=34 step=1 default=12 value=15
              video_gop_closure (bool) : default=1 value=1
             video_bitrate_mode (menu) : min=0 max=1 default=0 value=0 flags=update
                                0: Variable Bitrate
                                1: Constant Bitrate
                  video_bitrate (int)  : min=0 max=27000000 step=1 default=6000000 value=6000000
             video_peak_bitrate (int)  : min=0 max=27000000 step=1 default=8000000 value=8000000
      video_temporal_decimation (int)  : min=0 max=255 step=1 default=0 value=0
                     video_mute (bool) : default=0 value=0
                 video_mute_yuv (int)  : min=0 max=16777215 step=1 default=32896 value=32896
            spatial_filter_mode (menu) : min=0 max=1 default=0 value=0 flags=update
                                0: Manual
                                1: Auto
                 spatial_filter (int)  : min=0 max=15 step=1 default=0 value=0 flags=slider
       spatial_luma_filter_type (menu) : min=0 max=4 default=0 value=1
                                0: Off
                                1: 1D Horizontal
                                2: 1D Vertical
                                3: 2D H/V Separable
                                4: 2D Symmetric non-separable
     spatial_chroma_filter_type (menu) : min=0 max=1 default=0 value=1
                                0: Off
                                1: 1D Horizontal
           temporal_filter_mode (menu) : min=0 max=1 default=0 value=0 flags=update
                                0: Manual
                                1: Auto
                temporal_filter (int)  : min=0 max=31 step=1 default=0 value=8 flags=slider
             median_filter_type (menu) : min=0 max=4 default=0 value=0 flags=update
                                0: Off
                                1: Horizontal
                                2: Vertical
                                3: Horizontal/Vertical
                                4: Diagonal
     median_luma_filter_minimum (int)  : min=0 max=255 step=1 default=0 value=0 flags=inactive slider
     median_luma_filter_maximum (int)  : min=0 max=255 step=1 default=255 value=255 flags=inactive slider
   median_chroma_filter_minimum (int)  : min=0 max=255 step=1 default=0 value=0 flags=inactive slider
   median_chroma_filter_maximum (int)  : min=0 max=255 step=1 default=255 value=255 flags=inactive slider
      insert_navigation_packets (bool) : default=0 value=0
 

具体的には 例えば MPEG2のビットレートを落としてキャプチャ動画のサイズを落とすなどが考えられます

$ v4l2-ctl -d /dev/video0 -c video_bitrate=2000000
 

ハードディスクレコーダとして利用する場合は 事前に画質やチャンネルをチューニングした上で

$ cat /dev/video0 > movie.mpg
 

と単純にストリームをファイルにコピーするだけです
実際はスクリプトやツールなどを利用する形となるでしょう

ivtv-utils-1.4.0 では record-v4l2.pl を利用していますので紹介します

まずは record-v4l2.pl の情報表示機能からです

$ record-v4l2.pl --list-inputs
record-v4l2.pl 1.33 for use with http://ivtv.sf.net/
Available Inputs:
0: Tuner 1
1: S-Video 1
2: Composite 1
$
 

上記の感じで入力ソースの情報が取得できます シェルでコマンドラインを叩く点は一緒です
また 「record-v4l2.pl –help」 でオプション説明が得られます

S-Videoで 10秒間録画してみます

$ record-v4l2.pl -d /dev/v4l/video0 -I 'S-Video 1' -D /mnt/share/movie --directory-format "" -o test.mpg -t 10
$
 

オプションの説明ですが
-I 'S-Video 1' でキャプチャカードと入力ソースを指定します
-D は録画したファイルの置き場所となるベースディレクトリの指定です
–directory-format を空白に設定しています
録画毎にベースディレクトリにサブディレクトリを別けて保存したい場合はフォーマットを指定します
S-Video_1-20110828-0959/ みたいな感じでディレクトリを別けることが可能です
空白を設定することで ベースディレクトリ直下に録画ファイルを保存してくれます

キャプチャした映像は下記のように保存されていました
ひかりTV アナログキャプチャ画像
ソースの映像は フレッツ光のひかりTVです
綺麗にキャプチャできていますが ソースがHDのためキャプチャの上下部分に非映像領域があります

Linux-3.7.8では下記のエラーが出ました

record-v4l2.pl 1.33 for use with http://ivtv.sf.net/
Error:  Video Standard = 'NTSC' is invalid!
Valid Standards are: NTSC-M
 

「record-v4l2.pl --list-standard」 で指定可能な映像規格が表示されます
Linux-3.7.8では NTSCが使えなくなっているようです
対処として record-v4l2.pl に -s NTSC-M オプションを指定すれば問題なく
録画できます

 

ファームウェアのロードタイミングについて

↑でファームウェアのロードの仕組みについて触れましたが
実際にファームウェアを ロード/アンロード するタイミングは /dev/video0 を open()/close()するタイミングのようです
具体的には Xineを開いたり閉じたりしたとき キャプチャの開始/終了時 となります

hotplug動作ログ
open()時 DEVPATH=/devices/pci0000:00/0000:00:0b.0/firmware/firmware-0000:00:0b ACTION=add SYSFS=/sys FIRMWARE=v4l-cx2341x-enc.fw
close()時 DEVPATH=/devices/pci0000:00/0000:00:0b.0/firmware/firmware-0000:00:0b ACTION=remove SYSFS=/sys FIRMWARE=v4l-cx2341x-enc.fw

CDemu で CD-ROMイメージをマウントする

CDemuとは

Windowsでは daemontoolsが有名ですが
それと同様の機能を提供します
  • 仮想ドライブ /dev/sr〜 の提供
  • b6t,c2d,ccd,cdi,cif,cue,daa,iso,mds,nrg,toc 形式のサポート
  • CDオーディオのサポート

パッケージ構成

パッケージ構成の説明
cdemu-daemon CDemuのサーバ クライアントからの制御を受け付ける
cdemu-client コマンドラインのフロントエンド 仮想イメージの追加/削除をサーバに要求する
VHBA カーネルモジュール /dev/sr〜 の処理を行う /dev/vhba_ctl をサポート
libdaemon 常駐機能を実装するライブラリ
libmirage CD/DVDのイメージファイルを処理するライブラリ

このブログでは CDemuのソースコードからのインストールの注意点と 利用方法の概要説明 CDemu動作の問題点とその解決方法について記載しています

インストール

検証時の構成
CPU AMD Turion64 MT-37 (2GHz)
OS Linux-2.6.30.5
DVDドライブ /DC-DW1670
ATAPI内蔵
DVD-RW x6, DVD+RW x8, DVD-R x16, DVD+R x16
DVD-RAM x5, CD-R x48, CD-RW x32
コンパイル環境 GCC-4.1.2(i686), GLIBC-2.5
D-Bus dbus-1.0.2
VHBA vhba-module-1.2.1
libmirage libmirage-1.2.0
cdemu-daemon cdemu-daemon-1.2.0
cdemu-client cdemu-client-1.2.0
最終検証日 2010-5-23
ここでは cdemuのインストールについて 注意点等を記載します

libdaemon
libmirage については
ソースコードを展開して ./configure → make → make install (root権限で)
でインストールできました

vhba-module については
ソースコードを展開後 以下の手順でインストールします

$ make modules
$ su
# make module_install
 

ただし (Linuxの古いバージョン等) 以下のエラーが発生する場合

CC [M]  〜/vhba-module-1.0.0/vhba.o
〜/vhba-module-1.0.0/vhba.c:793:51: error: マクロ "INIT_WORK" は引数を 3 要求しますが、2 個しか与えられていません
 

INIT_WORKマクロの仕様が linuxカーネル側で修正になっているので vhba.c 793行目 を修正します

INIT_WORK(&vhost->scan_devices, vhba_scan_devices);
↓
INIT_WORK(&vhost->scan_devices, vhba_scan_devices, &vhost->scan_devices);

また 少なくとも kernel-2.6.24 以降では CFLAGSの設定でエラーが出るようです

make -C /lib/modules/`uname -r`/build M=/home/admin/vhba-module-1.0.0 modules
make[1]: Entering directory `/usr/src/linux-2.6.24'
scripts/Makefile.build:46: *** CFLAGS was changed in "/home/admin/vhba-module-1.0.0/Makefile". Fix it to use EXTRA_CFLAGS。中止。
make[1]: *** [_module_/home/admin/vhba-module-1.0.0] エラー 2
make[1]: Leaving directory `/usr/src/linux-2.6.24'
make: *** [modules] エラー 2
 

CFLAGS を EXTRA_CFLAGS に変えてくださいとのエラーのように見えます Makefile を以下のように修正します

2 PACKAGE = vhba-module-$(VHBA_VERSION)
3 
4 CFLAGS += -DVHBA_VERSION=\"$(VHBA_VERSION)\"
5 
6 obj-m += vhba.o
↓
2 PACKAGE = vhba-module-$(VHBA_VERSION)
3 
4 EXTRA_CFLAGS += -DVHBA_VERSION=\"$(VHBA_VERSION)\"
5 
6 obj-m += vhba.o
 

さらに以下のようなエラーが出る場合

make -C /lib/modules/`uname -r`/build M=/home/admin/vhba-module-1.0.0 modules
make[1]: Entering directory `/usr/src/linux-2.6.24'
  CC [M]  /home/admin/vhba-module-1.0.0/vhba.o
/home/admin/vhba-module-1.0.0/vhba.c: In function 'do_response':
/home/admin/vhba-module-1.0.0/vhba.c:523: error: 'struct scatterlist' has no member named 'page'
make[2]: *** [/home/admin/vhba-module-1.0.0/vhba.o] エラー 1
make[1]: *** [_module_/home/admin/vhba-module-1.0.0] エラー 2
make[1]: Leaving directory `/usr/src/linux-2.6.24'
make: *** [modules] エラー 2
 

少なくともカーネル 2.4.24以降の struct scatter_list のメンバ要素が仕様修正されてるようで vhba.c に以下の修正を加えました

522 
523             kaddr = kmap_atomic(sg[i].page, KM_USER0);
524             memcpy(kaddr + sg[i].offset, kbuf, len);
525             kunmap_atomic(kaddr, KM_USER0);
526 
↓
522 
523             kaddr = kmap_atomic(sg[i].page_link, KM_USER0);
524             memcpy(kaddr + sg[i].offset, kbuf, len);
525             kunmap_atomic(kaddr, KM_USER0);
526 
 

また udevのルール設定に追加が必要です 次のような 1行を追加しておきます

KERNEL=="vhba_ctl", NAME="%k", MODE="0660", OWNER="root", GROUP="users"
 

インストールがうまくいったら モジュールがロードできるようになります

# insmod /lib/modules/〜/extra/vhba.ko
# lsmod
Module                  Size  Used by
vhba                    7168  0 
nvidia               6816276  22 
 

vhba.ko は Linuxのシステム起動時に自動的に読み込まれるように設定しておくと便利です

次に cdemu-daemon 本体をインストールします ソースコードを展開後

$ ./configure --with-dbus-system-dir=/usr/local/etc/dbus-1/system.d
〜
 cdemu-daemon 1.2.0 configure summary:
  Prefix:                    /usr/local
  dbus-1 system.d dir:       /usr/local/etc/dbus-1/system.d
  C Compiler:                gcc -std=gnu99
  CFLAGS:                    -g -O2
$ make
$ su
# make install
 

–with-dbus-system-dir の設定は環境によっては /etc/dbus-1/system.d かもしれません
インストールが完了すれば cdemud のコマンドが使えるようになっています

最後に cdemu-client をインストールします ソースコードを展開後

$ make
$ su
# make install
 

インストール後は cdemu コマンドが使えるようになります

利用方法

まず 前提が 2つあり
1つ目は VHBAのカーネルモジュールがロードされている必要があるということです
(lsmodで確認 なければ modprobe vhba コマンドでロード完了です)
2つ目は D-Busも正しく起動して常駐されている必要があるということです
(ps -axで確認 なければ root権限にて dbus-daemon –system で起動されるか試してください)

いよいよ本番ですが cdemud を常駐させます rootのコンソールを 1枚立ち上げて

# cdemud -a alsa
 - num devices: 1
 - ctl device: /dev/vhba_ctl
 - audio driver: alsa
 - bus type: system
 

とりあえず フロントエンドで常駐した状態になります

  • num_devices は cdemud に -n オプションを付けることで指定できる
  • バックエンドで常駐するには -d をつければよいはずですが 手元の環境では確認できませんでした
  • audio_backend は -a オプションで指定します libaoが適切に導入されている必要があります

cdemudが起動することで /dev/sr0 が 仮想CDデバイスとして見えるようになるはずです

以降は主に cdemu コマンドで CDイメージを操作することになります
まずは イメージのロードから

# cdemu load 0 ~/test.cue
#
 

上記コマンドでは test.cue のキューシートを指定して読み込む指定です
何事もエラーがでなければ OKです /dev/sr0 に CDイメージがセットされているはずです

仮想CDデバイスの利用状況は以下のように確認できます

# cdemu status
Devices status:
DEV   LOADED     TYPE       FILENAME
0     1          PARSER-CUE /root/test.cue
 

では 実際にロードしたイメージが 通常のCDデバイスと同じく扱えるか確認してみます

# mount -t iso9660 -o ro /dev/sr0 /mnt/cdrom
# ls /mnt/cdrom
AUTORUN.INF              Setup.exe     congrats.avi  layout.bin
Autorun.exe              _INST32I.EX_  credits.avi   lemmings.box
DATA.TAG                 _ISDel.exe    data1.cab     os.dat
DirectX7.0a              _Setup.dll    data1.hdr     setup.bmp
Intel Indeo Readme.txt   _sys1.cab     delreg.exe    setup.ins
Lemmings Revolution.exe  _sys1.hdr     failed.avi    setup.lid
Patch.box                _user1.cab    frontend.avi  splash256.bmp
SETUP.INI                _user1.hdr    gameover.avi
SavedGame.dat            complete.avi  lang.dat
 

Windows用のゲームの CD-ROMをマウントした結果 正しくファイルシステムが見えていることが分かります

イメージを利用し終えたら /dev/sr0 での利用を次のように解除します

# umount /mnt/cdrom
# cdemu unload 0
 

以上が CDemuの基本的な流れとなります
cdemu load と cdemu unload コマンドで LinuxにおいてもCDイメージが扱え非常に便利です

注意点としては cdemu load する時のイメージパスに日本語を含む場合は EUC-JP でなく UTF-8 で指定しないと受け付けてもらえず EUC-JPの環境では苦労することです

CDemuの問題について

検証環境にて CDemuを利用して遭遇した問題点について 解決できたのがあるので紹介します
問題点については以下のとおりです
  • CD-DAオーディオの問題 cdda-playerによる演奏がうまく鳴らない現象
  • データトラックへアクセスできない不具合 PC-EngineのCD-ROMなど特殊な構成で発生
まず CD-DAオーディオの問題ですが
下記のように cdda-player コマンドによる CD-DA演奏でどのトラックも音が鳴らず一瞬でトラック終了に達してしまいます

  $ cdda-player /dev/sr0
 

CDemu + cdda-player 失敗画面
実際は 一瞬音が鳴るのですが すぐに停止状態になってしまいます

ちなみに cdda-playerは libcdioパッケージの付属ツールです コマンドラインからCD演奏できます
cdemu-daemonでは 実際の CDデバイスに対する ioctl()処理をエミュレートする機能がありますが
その動作を解析した結果 問題箇所と回避策を見つけました

cdda-playerでは 演奏開始直後に CDデバイスに対して MODE SENSEコマンドを発行していたのです
MODE SENSEとは CDドライブの能力情報をドライブから取得するコマンドです
cdemuにおいては 下記のソースコード(cdemu-device.c)で

2770     } packet_commands[] = {
2771         { PC_GET_EVENT_STATUS_NOTIFICATION,
2772           "GET EVENT/STATUS NOTIFICATION",
2773           __cdemud_device_pc_get_event_status_notification,
2774           FALSE },
2775         { PC_GET_CONFIGURATION,
2776           "GET CONFIGURATION",
2777           __cdemud_device_pc_get_configuration,
2778           TRUE, },
2779         { PC_INQUIRY,
2780           "INQUIRY",
2781           __cdemud_device_pc_inquiry,
2782           FALSE },
2783         { PC_MODE_SELECT_6,
2784           "MODE SELECT (6)",
2785           __cdemud_device_pc_mode_select,
2786           TRUE },
2787         { PC_MODE_SELECT_10,
2788           "MODE SELECT (10)",
2789           __cdemud_device_pc_mode_select,
2790           TRUE },
2791         { PC_MODE_SENSE_6,
2792           "MODE SENSE (6)",
2793           __cdemud_device_pc_mode_sense,
2794           TRUE },
2795         { PC_MODE_SENSE_10,
2796           "MODE SENSE (10)",
2797           __cdemud_device_pc_mode_sense,
2798           TRUE },
2799         { PC_PAUSE_RESUME,
2800           "PAUSE/RESUME",
2801           __cdemud_device_pc_pause_resume,
2802           FALSE /* Well, it does... but in it's own, unique way :P */ },
 

各コマンドの 処理方法を定義していますが
それぞれ TRUE FALSE とある部分が コマンドを処理するときに CD-DAを停止するかどうかのフラグで
MODE_SENSE においては TRUE つまり 停止となっています

2792           "MODE SENSE (6)",
2793           __cdemud_device_pc_mode_sense,
2794           FALSE },
2795         { PC_MODE_SENSE_10,
2796           "MODE SENSE (10)",
2797           __cdemud_device_pc_mode_sense,
2798           FALSE },
 

上記のように FALSEに設定することで cdda-playerが正常に演奏されるようになりました

(実際のデバイスの振舞いと一致しているかどうかは未確認です
また cdda-player以外の再生環境では問題はでないかもしれません)

ちなみに CDemuでは 音声ファイルを libsndfileに任せているので
sndfile-play コマンドで演奏できるフォーマットは CUEシートに入力できます

FILE "test1.ogg" WAVE
 TRACK 1 AUDIO
 INDEX 1 00:00:00
FILE "test2.ogg" WAVE
 TRACK 2 AUDIO
 INDEX 1 00:00:00
 

上記のようなCUEシートで Oggのような圧縮音声形式もCDイメージ化でき大変コンパクトに収まります
(残念ながら mp3 は sndfileで扱ってなかったので 検証環境でCDイメージ化は不可でした)

次に データトラックへのアクセスの問題です
現象としては Mednafen(マルチゲームエミュレータ) + 「アルナムの牙」(PC-Engine CD-ROM2ゲーム)の CUEシートで全く動作しないという問題です
CUEシートは 以下のとおりです

FILE "track_01.wav" WAVE
 TRACK 1 AUDIO
 INDEX 1 00:00:00
FILE "track_02.bin" BINARY
 TRACK 2 MODE1/2352
 INDEX 1 00:00:00
FILE "track_03.wav" WAVE
 TRACK 3 AUDIO
 INDEX 1 00:00:00
FILE "track_04.wav" WAVE
 TRACK 4 AUDIO
 INDEX 1 00:00:00
FILE "track_05.wav" WAVE
 TRACK 5 AUDIO
 INDEX 1 00:00:00
FILE "track_06.wav" WAVE
 TRACK 6 AUDIO
 INDEX 1 00:00:00
FILE "track_07.wav" WAVE
 TRACK 7 AUDIO
 INDEX 1 00:00:00
FILE "track_08.wav" WAVE
 TRACK 8 AUDIO
 INDEX 1 00:00:00
FILE "track_09.wav" WAVE
 TRACK 9 AUDIO
 INDEX 1 00:00:00
FILE "track_10.wav" WAVE
 TRACK 10 AUDIO
 INDEX 1 00:00:00
FILE "track_11.wav" WAVE
 TRACK 11 AUDIO
 INDEX 1 00:00:00
FILE "track_12.wav" WAVE
 TRACK 12 AUDIO
 INDEX 1 00:00:00
FILE "track_13.wav" WAVE
 TRACK 13 AUDIO
 INDEX 1 00:00:00
FILE "track_14.wav" WAVE
 TRACK 14 AUDIO
 INDEX 1 00:00:00
FILE "track_15.wav" WAVE
 TRACK 15 AUDIO
 INDEX 1 00:00:00
FILE "track_16.wav" WAVE
 TRACK 16 AUDIO
 INDEX 1 00:00:00
FILE "track_17.wav" WAVE
 TRACK 17 AUDIO
 INDEX 1 00:00:00
FILE "track_18.wav" WAVE
 TRACK 18 AUDIO
 INDEX 1 00:00:00
FILE "track_19.wav" WAVE
 TRACK 19 AUDIO
 INDEX 1 00:00:00
FILE "track_20.wav" WAVE
 TRACK 20 AUDIO
 INDEX 1 00:00:00
FILE "track_21.wav" WAVE
 TRACK 21 AUDIO
 INDEX 1 00:00:00
FILE "track_22.wav" WAVE
 TRACK 22 AUDIO
 INDEX 1 00:00:00
FILE "track_23.wav" WAVE
 TRACK 23 AUDIO
 INDEX 1 00:00:00
FILE "track_24.wav" WAVE
 TRACK 24 AUDIO
 INDEX 1 00:00:00
FILE "track_25.wav" WAVE
 TRACK 25 AUDIO
 INDEX 1 00:00:00
FILE "track_26.wav" WAVE
 TRACK 26 AUDIO
 INDEX 1 00:00:00
FILE "track_27.wav" WAVE
 TRACK 27 AUDIO
 INDEX 1 00:00:00
FILE "track_28.wav" WAVE
 TRACK 28 AUDIO
 INDEX 1 00:00:00
FILE "track_29.wav" WAVE
 TRACK 29 AUDIO
 INDEX 1 00:00:00
FILE "track_30.wav" WAVE
 TRACK 30 AUDIO
 INDEX 1 00:00:00
FILE "track_31.wav" WAVE
 TRACK 31 AUDIO
 INDEX 1 00:00:00
FILE "track_32.wav" WAVE
 TRACK 32 AUDIO
 INDEX 1 00:00:00
FILE "track_33.wav" WAVE
 TRACK 33 AUDIO
 INDEX 1 00:00:00
FILE "track_34.wav" WAVE
 TRACK 34 AUDIO
 INDEX 1 00:00:00
FILE "track_35.wav" WAVE
 TRACK 35 AUDIO
 INDEX 1 00:00:00
FILE "track_36.wav" WAVE
 TRACK 36 AUDIO
 INDEX 1 00:00:00
FILE "track_37.wav" WAVE
 TRACK 37 AUDIO
 INDEX 1 00:00:00
FILE "track_38.wav" WAVE
 TRACK 38 AUDIO
 INDEX 1 00:00:00
FILE "track_39.wav" WAVE
 TRACK 39 AUDIO
 INDEX 1 00:00:00
FILE "track_40.wav" WAVE
 TRACK 40 AUDIO
 INDEX 1 00:00:00
FILE "track_41.wav" WAVE
 TRACK 41 AUDIO
 INDEX 1 00:00:00
FILE "track_42.wav" WAVE
 TRACK 42 AUDIO
 INDEX 1 00:00:00
 

PC-Engineの CDトラック構成は特殊で
1トラック目が音声(警告用) 2トラック目がデータ(プログラム) それ以降は 音声(CD-DA)
となっています ゲームによっては データトラックが最後に入ってくることもあります

Mednafenの起動時に固まってしまう問題で 問題のでないゲームもあり調査に時間がかかりました
結果 上記特殊トラック構成を扱う上での Linux(カーネル?)との相性問題にまで及んでいました

CUEシートのトラック構成は libmirageが扱っていますが 各トラックの開始セクタは次のようになっています

track01   start=-150   length=3743(sectors)    AUDIO  (2352bytes/sector)
track02   start=3593   length=45336(sectors)   BINARY (2352bytes/sector)
track03   start=48929  length=2925(sectors)    AUDIO  (2352bytes/sector)
〜
 

track01 の 開始セクタが -150 と負の値になっているのは プリギャップを加味してるためでここは問題ありません

問題となっているのは track02 です
現行の CDemudでは 2048bytes/sector しかデータトラックの読み出しをサポートしていません
ソースコードでは cdemud-device.c にあたります

1462         /* READ 10/12 should support only sectors with 2048-byte user data      */
1463         gint tmp_len = 0;
1464         guint8 *tmp_buf = NULL;
1465         guint8 *cache_ptr = _priv->buffer+_priv->buffer_size;
1466 
1467         mirage_sector_get_data(MIRAGE_SECTOR(cur_sector), &tmp_buf, &tmp_le     n, NULL);
1468         if (tmp_len != 2048) {
1469             CDEMUD_DEBUG(self, DAEMON_DEBUG_MMC, "%s: sector 0x%X does not      have 2048-byte user data (%i)\n", __debug__, sector, tmp_len);
1470             g_object_unref(cur_sector);
1471             __cdemud_device_write_sense_full(self, SK_ILLEGAL_REQUEST, ILLE     GAL_MODE_FOR_THIS_TRACK, 1, sector);
1472             return FALSE;
1473         }
1474
 

mirage_sector_get_data() でデータを読みだした結果 2048バイトでないとエラーとなります
ここを 以下のように修正しました

1462         /* READ 10/12 should support only sectors with 2048-byte user data */
1463         gint tmp_len = 0;
1464         guint8 *tmp_buf = NULL;
1465         guint8 *cache_ptr = _priv->buffer+_priv->buffer_size;
1466         gint tmp_type = 0;
1467         
1468         mirage_sector_get_data(MIRAGE_SECTOR(cur_sector), &tmp_buf, &tmp_len, NULL)     ;
1469 /*
1470  Add support some 2352bytes/sector format.
1471 */
1472         switch (tmp_len) {
1473             case 2048:  /* MODE1 */
1474                 memcpy(cache_ptr, tmp_buf, 2048);
1475                 _priv->buffer_size += 2048;
1476                 break;
1477             case 2352:  /* MODE2 FORM1 etc.*/
1478                 mirage_sector_get_sector_type(MIRAGE_SECTOR(cur_sector), &tmp_type, NULL);         
1479                 if ((tmp_type == MIRAGE_MODE_MODE1) || (tmp_type==MIRAGE_MODE_MODE2_FORM1)) {      
1480                     memcpy(cache_ptr, tmp_buf + 16, 2048);
1481                     _priv->buffer_size += 2048; 
1482                     break;
1483                 }   
1484                 /* Otherwise, I dont know where 2048-byte user data is in. */
1485             default:
1486                 CDEMUD_DEBUG(self, DAEMON_DEBUG_MMC, "%s: sector 0x%X does not have 2048-byte user data (%i)\n", __debug__, sector, tmp_len);
1487                 g_object_unref(cur_sector);
1488                 __cdemud_device_write_sense_full(self, SK_ILLEGAL_REQUEST, ILLEGAL_MODE_FOR_THIS_TRACK, 1, sector);
1489                 return FALSE;
1490         }
1491         
 

CD-ROMのデータトラックは 通常 1セクタあたり 2048バイトのデータ構成となっていますが
実際は ヘッダ情報や CRCなどの付加情報が前後に含まれています

上記コードは 2352バイトのフォーマットにおいても データ部分 2048バイトを抜き出す対応を追加したものです
ただし MODE1 など 一部のフォーマットのみの対応なので完全ではありません
そもそも CD-ROMからイメージを抜き出す際に MODE1(2048bytes/sector)を指定すれば ここの問題は発生しません

で 問題はさらに続きます
Mednafenで PC-Engineの処理を解析した結果 次の不具合が確認されました
「Mednafenでは データトラックの読み込み開始で 開始セクタ=3593 を指定しているのに
CDemuにおいては 開始セクタ=3592 のセクタリードが要求されている」

Mednafenとしてのデバイスアクセス ioctl() 開始セクタ=3593 で要求

Linuxカーネルのデバイスドライバ処理

VHBA (仮想ドライバ)

CDemu 開始セクタ=3592 の要求をイベントとして受ける

Linuxカーネルを経由することで セクタ番号がずれているように思われます
Linuxカーネルの内部動作まで確認しきれませんので いろいろ検証した結果以下の対応としました

「(Linuxでは?)CDトラックの開始セクタが 偶数セクタ番号となっているため
libmirageに調整処理を追加して トラックの開始セクタ番号が必ず偶数となるように合わせる」

これが一番 手短な改修でした libmirage のソースコード mirage-session.c に追加しました

  91         cur_track_address += track_length;
  92 
  93 /* track start address may be even-number.
  94    I found a troube at following environment.
  95     (MIXED-MODE)
  96      track01  start=-150  length=3743(sectors)   AUDIO  (2352bytes/sector)
  97      track02  start=3593  length=45336(sectors)  BINARY (2048bytes/sector)
  98      track03  start=48929 length=2925(sectors)   AUDIO  (2352bytes/sector)
  99      ...
 100    track02(DATA) start sector is just 3593, but Linux? set ioctl() start a     ddress 3592 (-1).
 101    So, CDemu is going to access to "track01" and fails.
 102    (Because CDemu fails to access to 2352bytes/sector at current version.)
 103 */
 104         if ( cur_track_address % 2 )  cur_track_address++;
 105     }
 106 
 107     return TRUE;
 

CUEシートからトラック情報を読み取る処理 に追加し 開始セクタ位置を調整しました

以上の作業で ようやく 「アルナムの牙」が動作しました
Mednafen + CDemu(.CUE) アルナムの牙
パソコンで PC-Engineのゲームができるようになるとは いい時代です
残りの CD-ROMゲームも吸い出してしまおう

OpenOffice.org のビルド

OpenOffice.org 2.3.0 ビルド

OpenOffice をソースコードからビルドしました
手順と ローカルビルドの tar.gz パッケージをここに公開します

OpenOffice.org 2.3.0 ja-071021版 localビルド
(linux-2.6-intel) (110MB)

インストール方法

  1. root権限で作業を行います
  2. cd /opt でディレクトリに移ります (/opt 場所以外での正常動作は未確認です)
  3. 上記 アーカイブファイルを展開します tar -xzf 〜/OOo_2.3.0_071021_unxlngi6_install_ja.tar.gz ja/linux-2.6-intel/buildroot/opt/ –strip-path=4
  4. ファイルのインストールは完了です
  5. 環境設定を行います 環境変数 PATH に /opt/openoffice.org2.3/programを追加します

起動方法

  • 空のプロジェクト : soffice を実行
  • Writer(文書ドキュメント) : swriter を実行
  • Calc(表計算) :
    scalc を実行
  • Impress(プレゼンテーション) : simpress を実行
  • Draw(図形描画) : sdraw を実行
  • Base(データベース) : sbase を実行
  • Math(数式記述) : smath を実行

↑で配布しているバイナリは 依存しているソフトウェアが全て「インストール済」であることを前提としています 例えば 「STLportライブラリが不足しているため起動できない」といったエラーが出るかもしれません その場合は別途ソフトウェアをインストールする必要があります

以降は OpenOfficeのビルドの時に作業したメモです
OpenOfficeは ビルドが難解なソフトの 1つで 理由としては

  • 他の多くの オープン系ソフトに依存している (ここが オープンソフトの利点でもありますが)
  • OpenOffice自体が巨大なプロジェクト ビルドに 3GB程のディスク領域が必要です
  • システムの環境にも依存する

従って 以降の方法が全ての環境で成功する訳ではありません
ビルドの流れは大まかに

  1. ソースの展開
  2. 不足ファイルの追加
  3. configure 実施
  4. dmake生成
  5. dmake実施
となります

前準備

必要なソフトについて ビルド方法解説ページ にも説明がありますが

  • Java開発環境(JDK) と ANT
  • Firefoxビルド済のディレクトリ
  • EPM(ESP Package Manager) パッケージツール .rpm や .deb 形式のアーカイブを作る場合必要
  • libmspack (.exe や .cab圧縮 のアーカイブを処理する)
  • libgsf-1 (構造化ファイル形式を処理する)
  • libwpd (Wordperfect文書を処理する)
  • ttf-bitstream-veraフォント (必要らしい TrueTypeなので注意)

あたりが少なくとも必要です インストール方法についてはここでは触れません

また次のツールは 後述のインストールの部分で触れます この段階でインストールの必要はありません

  • libgcc_s.so.1 libstdc++.so.5 (gccのバージョンに関わらず必要)
  • General Polygon Clipper (イメージのクリッピング処理)
  • unowinreg.dll (DLL?)

インストール

まず ソースコードをダウンロードします
OpenOffice.org日本語プロジェクト
の「ダウンロード」リンクから辿れますが 結局英語のページからのダウンロードになります
OOoダウンロードページ

  • sdk source package (OOo_2.3.0_src_sdk.tar.bz2)
  • core source package (OOo_2.3.0_src_core.tar.bz2)
  • system source package (OOo_2.3.0_src_system.tar.bz2)
  • binfilter source package (OOo_2.3.0_src_binfilter.tar.bz2)
  • l10n source package (OOo_2.3.0_src_l10n.tar.bz2)

全てダウンロードしておきましょう

Linuxシステムにて ビルド用ディレクトリを作成します

$ mkdir ooo
$ cd ooo

ダウンロードしたソースを展開します

$ tar -xjf ../OOo_2.3.0_src_sdk.tar.bz2
$ tar -xjf ../OOo_2.3.0_src_binfilter.tar.bz2
$ tar -xjf ../OOo_2.3.0_src_core.tar.bz2
$ tar -xjf ../OOo_2.3.0_src_system.tar.bz2
$ tar -xjf ../OOo_2.3.0_src_l10n.tar.bz2
$ cd OOG680_m5

libgcc_s.so.1 libstdc++.so.5 を手作業で追加
gcc-3.3.xまでの gccパッケージに含まれているので このバージョン以上の gccを使っている場合
別途パッケージから個別に取り出すか gcc-3.3.x をローカルビルドして取り出す必要があります
libgcc_s.so.1 libstdc++.so.5 は solver/680/unxlngi4.pro/lib/ にコピーしておくかライブラリパスの通ったディレクトリに配置します

unowinreg.dll が必要
自力でビルドする場合 migwin32 のクロスコンパイル環境が必要
今回はプリコンパイル済のファイルを sun からダウンロードして利用します external/unowinreg/ にコピーしておきます

GPCを手作業追加する
ここ から gpc232.zip を取得して external/gpc/ に解凍します
gpc.c gpc.h が少なくとも入っている必要があります

configure 実施

$ cd config_office
$ ./configure --prefix=/opt/openoffice.org2.3 --with-package-format=native --enable-cairo --disable-kdeab --enable-gcjaot --with-openldap --with-system-mozilla --with-firefox --with-xulrunner --with-system-stdlibs --with-system-mspack --with-system-zlib --with-system-jpeg --with-system-expat --with-system-freetype --with-system-libwpd --with-system-libxml --with-system-python --with-system-hsqldb --with-hsqldb-jar=/opt/java/hsqldb/lib/hsqldb.jar --with-system-xml-apis --with-xml-apis-jar=/usr/local/apache-ant-1.7.0/lib/xml-apis.jar --with-system-xerces --with-xerces-jar=/usr/local/apache-ant-1.7.0/lib/xercesImpl.jar --with-system-xalan --with-xalan-jar=/usr/local/jdk1.6.0/jre/lib/ext/xalan.jar --with-serializer-jar=/usr/local/jdk1.6.0/jre/lib/ext/serializer.jar --with-system-sablot --with-system-odbc-headers --with-system-xrender-headers --with-system-boost --with-system-sndfile --with-system-neon --without-myspell-dicts --with-system-hunspell --with-stlport4=/usr/local --with-jdk-home=/usr/local/jdk1.6.0 --with-java --with-ant-home=/usr/local/apache-ant-1.7.0 --with-perl-home=/usr --without-fonts --with-lang=ja --with-dict=ALL --with-use-shell=bash --with-build-version=local --with-x

…
…
**************************************************************************** 
*
* OpenOffice.org 680 configuration. 
* 
* 
* Configuration part of OpenOffice.org 680 build is finished. 
* 
* NB! Be aware that you might not be able to build OpenOffice.org if you 
* ignore any warning message that were generated during this configuration 
* process. 
* 
* - to prevent incompatibilities between internal libxslt and libxml2, the offic
e will be build with system-libxslt
*
*
* USAGE: 
* Source LinuxX86Env.Set (in tcsh) or LinuxX86Env.Set.sh (in sh)
* in order to set up the build-environment variables.
* 
* 
**************************************************************************** 
Configure completed
You may now run ./bootstrap in //OOG680_m5
***** WARNINGS ISSUED *****

$ cd -
$

–with-sysytem-* を多用しており依存するソフトウェアは ビルド&インストール済であるとしています

それではビルド作業に入ります

dmakeという makeツールを生成する必要があります

$ source LinuxX86Env.Set.sh
$ ./bootstrap
…
…
make[2]: Leaving directory `/〜/OOG680_m5/dmake'
make[1]: Leaving directory `/〜/OOG680_m5/dmake'

dmake has been successfully built

dmake copied to /〜/OOG680_m5/solenv/unxlngi6/bin/dmake
$

OpenOfficeのビルドを開始します

$ dmake/dmake
…
…

うまくいけば Athron 2.0GHz メモリ 1G で 3時間くらいです

…
…
... checking log file 〜/OOG680_m5/instsetoo_native/unxlngi6.pro/URE/native/logging/en-US/log_OOG680_en-US.log

***********************************************************
Successful packaging process!
***********************************************************
... creating log file log_OOG680_en-US.log 

******************************************
... creating download installation set ...
******************************************
... including installation set into URE_1.3_linux_install_en-US.sh ... 
... checking log file 〜/OOG680_m5/instsetoo_native/unxlngi6.pro/URE/native/logging/en-US/log_OOG680_en-US.log

***********************************************************
Successful packaging process!
***********************************************************
... creating log file log_OOG680_en-US.log 
*** *** ** **:**:** **** (00:02 min.)

OOoイメージ

トラブルシューティング

以降 ビルド中にエラーが出て止まってしまう場合
システム環境に応じてソースコードを修正します

STLport(C++テンプレート)と競合してコンパイル失敗する問題が出る場合
solenv/inc/unxlngi6.mk を修正して回避します
(修正前)

 88 # flags for the C++ Compiler
 89 CFLAGSCC= -pipe $(ARCH_FLAGS)
 90 # Flags for enabling exception handling
 91 CFLAGSEXCEPTIONS=-fexceptions -fno-enforce-eh-specs
 92 # Flags for disabling exception handling
 93 CFLAGS_NO_EXCEPTIONS=-fno-exceptions

(修正後)

 88 # flags for the C++ Compiler
 89 CFLAGSCC= -pipe $(ARCH_FLAGS)
 90 # Flags for enabling exception handling
 91 CFLAGSEXCEPTIONS=-fexceptions -fno-enforce-eh-specs
 92 # Flags for disabling exception handling
 93 CFLAGS_NO_EXCEPTIONS=

./../unxlngi6.pro/lib/check_libpyuno.so: undefined symbol: forkpty の
エラーが出てしまう場合

forkpty() のシンボル未定義エラーが原因です
pyuno/source/module/makefile.mk を修正して libutil とリンクするようにします
(修正前)

 40
 41 LINKFLAGSDEFS = # do not fail with missing symbols
 42

(修正前)

 40
 41 LINKFLAGSDEFS = -lutil # do not fail with missing symbols
 42

BOOL識別子が 多重定義されている旨のエラーが出てしまう場合
solver/680/unxlngi6.pro/inc/tools/solar.h を修正して BOOLの多重定義を回避します
(修正前)

 35
 36 #ifndef _SOLAR_H
 37 #define _SOLAR_H
 38

(修正後)

 35
 36 #ifndef _SOLAR_H
 37 #define _SOLAR_H
 38 #define _OBJC_OBJC_H_
 39

1行 _OBJC_OBJC_H_ を定義するコードを追加します

printf() の関数が unresolved symbol のエラーとなってしまう場合
sc/source/filter/excel/tokstack.cxx の部分であれば printf() 自体をコメントアウトします
(修正前)

741 ScMatrix* TokenPool::GetMatrix( unsigned int n ) const
742 {
743     if( n < nP_MatrixAkt )
744         return ppP_Matrix[ n ];
745     else
746         printf ("GETMATRIX %d >= %d\n", n, nP_MatrixAkt);
747     return NULL;
748 }

(修正後)

741 ScMatrix* TokenPool::GetMatrix( unsigned int n ) const
742 {
743     if( n < nP_MatrixAkt )
744         return ppP_Matrix[ n ];
745 //    else
746 //        printf ("GETMATRIX %d >= %d\n", n, nP_MatrixAkt);
747     return NULL;
748 }

この printf() 1回の表示のために libcと結合するのも気がひけるためです

lib〜.so がないと言われてビルドが停止する場合
外部の 共有ライブラリがないか パス指定が違うかもしれません
solenv/inc/libs.mk を編集して
該当のライブラリの記述があるか あればパス指定が間違えてないか 確認と修正をします
私の環境では libjpeg.so が /usr/lib/libjpeg.so だったのを /usr/local/lib/libjpeg.so としました
また libs.mk にも記述がない場合 単純に必要用件のパッケージがインストールされてないだけかもしれません

〜.h がないと言われてビルドが停止する場合
solenv/inc/settings.mk を編集して CFLAGS や CFLAGSCXX にパスを追加します (空白区切りで列挙)
私の環境では nss とかいう文字列がちらほら見えたため Firefoxのビルドディレクトリを手動で指定する必要がありました 以下のようなディレクトリを追加しました

  • -I〜Firefoxソース/mozilla/security/nss/lib/pk11wrap
  • -I〜Firefoxソース/mozilla/security/nss/lib/cryptohi
  • -I〜Firefoxソース/mozilla/security/nss/lib/certdb
  • -I〜Firefoxソース/mozilla/security/nss/lib/util
  • -I〜Firefoxソース/mozilla/security/nss/lib/softoken
  • -I〜Firefoxソース/mozilla/security/nss/lib/pkcs7
  • -I〜Firefoxソース/mozilla/security/nss/lib/smime
  • -I〜Firefoxソース/mozilla/security/nss/lib/freebl
  • -I〜Firefoxソース/mozilla/security/nss/lib/freebl/ecl
  • -I〜Firefoxソース/mozilla/security/nss/lib/pkcs12

同様に libxmlsec関連でもヘッダファイルが見付からない旨のエラーが出ました
libxmlsec/makefile.mk を修正し Firefox関連のインクルードディレクトリを直接指定しました
(修正前)

111 xmlsec_LDFLAGS+=-L$(SYSBASE)$/usr$/lib
112 .ENDIF                  # "$(SYSBASE)"!=""
113
114 .IF "$(OS)$(COM)"=="LINUXGCC" || "$(OS)$(COM)"=="FREEBSDGCC"

(修正後)

111 xmlsec_LDFLAGS+=-L$(SYSBASE)$/usr$/lib
112 .ENDIF                  # "$(SYSBASE)"!=""
    113 xmlsec_CFLAGS+=-I〜Firefoxソース/mozilla/security/nss/lib/pk11wrap -I〜Firefoxソース/mozilla/security/nss/lib/cryptohi -I〜Firefoxソース/mozilla/security/nss/lib/certdb -I〜Firefoxソース/mozilla/security/nss/lib/util -I〜Firefoxソース/mozilla/security/nss/lib/softoken -I〜Firefoxソース/mozilla/security/nss/lib/pkcs7 -I〜Firefoxソース/mozilla/security/nss/lib/smime -I〜Firefoxソース/mozilla/security/nss/lib/freebl -I〜Firefoxソース/mozilla/security/nss/lib/freebl/ecl -I〜Firefoxソース/mozilla/security/nss/lib/pkcs12
114
115 .IF "$(OS)$(COM)"=="LINUXGCC" || "$(OS)$(COM)"=="FREEBSDGCC"

ソースコードを修正したにも関わらず 同じエラーで止まってしまう場合
修正したソースコードが 他の関連するファイルに波及されておらず一旦 make cleanしたほうがよいかもしれません

$ dmake/dmake clean
…
…
$ source LinuxX86Env.Set.sh
$ cp solenv/unxlngi6/bin/dmake dmake/
$ dmake/dmake
…
…

ゲームCDのイメージ化

ゲームCD をパソコンに吸出して保存する方法を紹介します

流れとしてはこんな感じです
(1) CDからパソコンへの吸出し
(2) トラック毎にファイル分離
(3) 音声トラックの圧縮
(1) の状態でも (2)の状態ても CDイメージとしては利用可能です 保存を考えるなら圧縮が利いてファイルサイズの小さい (3) が便利です
今回は メガCDソフト「ファイナルファイトCD」を例に ゲームCD吸い出して圧縮方法を紹介します

(1) CDからパソコンへの吸出し

CDやDVDのデータをイメージ化してくれる
CloneCD
を利用しました
CloneCD3 起動画面
イメージ吸出しのボタンを押して
CloneCD3 デバイス選択
CDデバイスの指定を行ないます
CloneCD3 吸出し設定
画面の右側に 認識されているトラック構成が表示されています
CUEシートは作成させる指定をします
最後に どのディレクトリに吸い出したデータを保存するか指定して開始します
吸出し結果
4つのファイルが作成されます

  • 〜.ccd が CloneCD用のトラック情報ファイル
  • 〜.cue が CUEシート
  • 〜.img が CDのイメージデータ
  • 〜.sub が CDのサブチャネルイメージデータ
では 吸い出したデータで早速遊んでみましょう
吸い出したデータをあたかも本物のCDと同じように扱える 仮想CDソフト を使います

仮想CDツールとしてDaemontoolsを利用しました
メガCDをエミュレーションするツールとしてGens32を利用しました

上記両ソフトがインストール済であることを過程して話をすすめます
Daemontools トレイ
アイコントレイに Daemontoolsが常駐しているのでそれをクリックして 先ほど吸い出した ファイナルファイト.cue を選択します
Gens32起動画面
Gens32を起動して 仮想CDデバイスからエミュレーションを開始します
Gens32ゲーム画面1
設定が正しければ 仮想CDのゲームが起動します 吸い出したデータが正しく動作することを確認したら 次の作業のために一旦ゲームを閉じて Daemontoolsもunmountしましょう

(2) トラック毎にファイル分離

CDのイメージ吸出しや イメージの利用という意味では (1)のみで十分ですが ここではもう一歩話を進めます つまりイメージの変換です 通常 1枚のCDには 複数のトラックが格納されています トラック毎にファイルとして分離してみます

CDイメージ処理ツールとしてCDmageを利用しました

CDmage 起動画面
CDmageの起動画面です CDイメージを指定して CDmageに読み込ませます
CDmage 読み込み直後
ファイナルファイトCD.cue を読み込ませると トラック情報が表示されます Track01 がゲーム用のバイナリデータで Track02〜Track29までがオーディオトラックであることが分かります
CDmage データトラック選択
まずデータトラックを分離します
データトラックである Track01 を選択して右クリック 「Extract Tracks」を選びます
CDmage データトラック読み出し
トラックの読み出し先と 格納形式を選択します
読み出し先として 「ファイナルファイトCD」 のディレクトリを新たに作って指定します
ファイル名形式として 「Track ?n.?e」 を指定しています 実際は 「Track 01.bin」 というファイル名になります
読み出し形式は 一般的なバイナリフォーマットである MODE1/2352 を指定します
設定が確認できたら 「Extract」 で実行します
CDmage オーディオトラック選択
次に同様にオーディオトラックを分離します
CDmageでは Ctrlキーを押しながら ファイルを選択することで 複数トラックを指定できます
CDmage オーディオトラック読み出し
読み出し先として 先ほど作った同じ 「ファイナルファイトCD」 のディレクトリを指定します
読み出し形式は Wave file 形式を指定します
また Wave fileのデフォルト拡張子を 「wav」 に変えるために 「Default Extensions」 を押して設定しましょう
CDmage 拡張子設定
Wave file の拡張子を wav と設定します
設定が確認できたら 「Extract」 で オーディオトラックを分離します
吸出し直後
うまくいったら 「ファイナルファイトCD」 のディレクトリの中身はこのようになります
最初に CDから吸い出した時のイメージのサイズはおよそ460MBで
分離したファイルについても総容量は 440MB とあまり変わりませんが
ファイルがトラック毎に分離されています
CUEシート追加
最後に これらトラックファイルをまとめる CUEシートを作ります
「ファイナルファイト.cue」 のようなテキストファイルを作成して エディッタで編集します

FILE "Track 01.bin" BINARY
 TRACK 1 MODE1/2352
 INDEX 1 00:00:00
FILE "Track 02.wav" WAVE
 TRACK 2 AUDIO
 PREGAP 00:02:00
 INDEX 1 00:00:00
FILE "Track 03.wav" WAVE
 TRACK 3 AUDIO
 INDEX 1 00:00:00
FILE "Track 04.wav" WAVE
 TRACK 4 AUDIO
 INDEX 1 00:00:00
FILE "Track 05.wav" WAVE
 TRACK 5 AUDIO
 INDEX 1 00:00:00
FILE "Track 06.wav" WAVE
 TRACK 6 AUDIO
 INDEX 1 00:00:00
FILE "Track 07.wav" WAVE
 TRACK 7 AUDIO
 INDEX 1 00:00:00
FILE "Track 08.wav" WAVE
 TRACK 8 AUDIO
 INDEX 1 00:00:00
FILE "Track 09.wav" WAVE
 TRACK 9 AUDIO
 INDEX 1 00:00:00
FILE "Track 10.wav" WAVE
 TRACK 10 AUDIO
 INDEX 1 00:00:00
FILE "Track 11.wav" WAVE
 TRACK 11 AUDIO
 INDEX 1 00:00:00
FILE "Track 12.wav" WAVE
 TRACK 12 AUDIO
 INDEX 1 00:00:00
FILE "Track 13.wav" WAVE
 TRACK 13 AUDIO
 INDEX 1 00:00:00
FILE "Track 14.wav" WAVE
 TRACK 14 AUDIO
 INDEX 1 00:00:00
FILE "Track 15.wav" WAVE
 TRACK 15 AUDIO
 INDEX 1 00:00:00
FILE "Track 16.wav" WAVE
 TRACK 16 AUDIO
 INDEX 1 00:00:00
FILE "Track 17.wav" WAVE
 TRACK 17 AUDIO
 INDEX 1 00:00:00
FILE "Track 18.wav" WAVE
 TRACK 18 AUDIO
 INDEX 1 00:00:00
FILE "Track 19.wav" WAVE
 TRACK 19 AUDIO
 INDEX 1 00:00:00
FILE "Track 20.wav" WAVE
 TRACK 20 AUDIO
 INDEX 1 00:00:00
FILE "Track 21.wav" WAVE
 TRACK 21 AUDIO
 INDEX 1 00:00:00
FILE "Track 22.wav" WAVE
 TRACK 22 AUDIO
 INDEX 1 00:00:00
FILE "Track 23.wav" WAVE
 TRACK 23 AUDIO
 INDEX 1 00:00:00
FILE "Track 24.wav" WAVE
 TRACK 24 AUDIO
 INDEX 1 00:00:00
FILE "Track 25.wav" WAVE
 TRACK 25 AUDIO
 INDEX 1 00:00:00
FILE "Track 26.wav" WAVE
 TRACK 26 AUDIO
 INDEX 1 00:00:00
FILE "Track 27.wav" WAVE
 TRACK 27 AUDIO
 INDEX 1 00:00:00
FILE "Track 28.wav" WAVE
 TRACK 28 AUDIO
 INDEX 1 00:00:00
FILE "Track 29.wav" WAVE
 TRACK 29 AUDIO
 INDEX 1 00:00:00

テキストファイルを編集する メモ帳 などで書きます
最初に CDから吸い出したときの CUEシートの内容を参考にして上記のように記述します
書き終わったら保存して メモ帳を閉じます

先ほどの作業で CDイメージの内容をトラック単位でファイルに分離しました
このデータも Daemontoolsで同様に 仮想CD として扱えます
先ほど編集した CUEシートを Daemontoolsに読み込ませて Gens32を起動してみます
Gens32ゲーム画面2
CUEシートの文法が正しければ 単一.img のマウントの時と同じく ゲームが読み込めるはずです 文法が間違っていれば Daemontoolsからエラーが報告されるので修正します

(3) 音声トラックの圧縮

最後に (ゲームするためでなく) 保存のための設定を行います
オーディオトラックを MP3 に圧縮してデータサイズを圧縮します

音声ファイルを処理するツールとしてCDexを利用しました

CDex 起動画面
CDexを起動して 「Convert」メニューから「Convert Wave file(s) to Compressed audio file(s)」
を選択して 「ファイナルファイトCD」のディレクトリを指定します
CDex wavファイル選択
オーディオトラックの各ファイルが一覧に現れるので 「Convert」 を押して圧縮開始します
圧縮された MP3 は CDex をインストールしたディレクトリの中の 「my music」ディレクトリの中に作成されます
MP3に置き換え
元の オーディオトラックファイルである .wav を削除して 作成した .mp3 ファイルで置き換えます
最終的に ファイルのサイズは全体で 64MB となりました サイズとしてはPCでの長期保存に便利です ただし ゲームを実行するには mp3 ファイルを元の wav ファイルに展開する作業が必要となりますので注意です

Daemontools が MP3オーディオ形式に対応してくれたら もっと便利になるのになぁ