FreeDB 操作 (執筆中)
音楽CDの曲名などをインターネットから自動取得するためには、CDDBを使う必要がある。
CDDBにはいろいろあるが、ここではFreeDBというものを使った方法を解説したい。
1.ディスクID
曲名などを自動取得するためには、CDを識別する必要がある。それは、CDDBによっていろいろな方法がとられているようだ。
今回のFreeDBでは、各曲の開始位置などの他にdiscidというものも使用している。
discidを算出するには、次の情報が必要だ。
・曲数
・曲ごとの開始位置(フレーム単位)
・曲ごとの長さ (フレーム単位)
フレームというのは、時分秒より小さい単位だと思えばいいだろう。
ただし、
1秒=75フレーム
であるので注意が必要だ。
2.情報の取得方法
さて、曲ごとの開始位置、長さだが、これは簡単に取得できる。
エクスプローラーなどでCDドライブを開くと、
Track01.cda
などといったファイル名をいくつか見ることができる。
*CD-TEXTやCD-EXTRAなどの特殊なフォーマットでは表示されないようだ。
これは曲の管理情報だ。この中に開始位置も入っている。
ただし、曲データそのものは入っていない。曲データを取り出すには、ドライブに直接アクセスする必要がある。
discidに必要な情報は、このファイルの中の次の情報だ。
+24h 開始位置(フレーム)
+25h 開始位置(秒)
+26h 開始位置(分)
+27h 開始位置(時)
+28h 曲の長さ(フレーム)
+29h 曲の長さ(秒)
+2Ah 曲の長さ(分)
+2Bh 曲の長さ(時)
これを全てのファイル(曲)ごとに取得すれば準備は完了だ。
ちなみに、
+16h 2バイト トラック番号(1から始まる)
+18h 4バイト CDシリアル番号
+1Ch 4バイト 開始位置(HSG)
+20h 4バイト 長さ(HSG)
となっている。
CDシリアル番号はCDPLAYER.INIでも使われているらしい。
3.計算準備
discidは、3つの要素から構成されている。
A.桁毎の合計値
B.全曲目の長さ(秒数)
C.曲数
では、それぞれを解説する。
A.桁毎の合計値
これは、わかりやすく説明すると次のようになる。
1.それぞれの曲毎に次の計算を行う。
・開始位置をフレーム単位に直す。
分*60*75 + 秒*75 + フレーム
で計算できる。
・その数値を、10進数の1桁毎に足した合計を算出する。
123456フレームなら、
1+2+3+4+5+6=21
となる。
この21という数字をそれぞれの曲毎に算出しておく。
2.算出した数値の合計値を算出し、それを255で割った余りをだす。
これが情報の1番目だ。
B.全曲目の長さ(秒数)
これは、
全曲の終了位置(m*60+s) − 1曲目の開始位置(m*60+s)
= (最終曲の開始位置 + 最終曲の長さ) − 1曲目の開始位置
の計算でよい。
「位置」はフレームを無視して計算する。
C.曲数
これは単純に、何曲あるかだけだ。
4.計算
さて、A、B、Cの3つの数値を次のようにする。
A << 24 | B << 8 | C
でてきた数値を、16進数に直し、8文字になるように先頭に0を補充すれば完成である。
5.データの取得
データを取得するには、
・cddbp(CDDBプロトコル)
・HTTP
・SMTP
のいずれかの方法でサーバーにアクセスする。
今回は、HTTPを使った方法を紹介する。
6.HTTPによるデータ取得
HTTPによる方法というのはコマンドをHTTPで送り、メッセージで結果を取得するものだ。ただし、discidを1発送ればOKというわけではない。
どうも、discidだけではCDを特定するのが難しいようで、discidと共にカテゴリーをキーとしているようだ。実際に、同じdiscidを違うカテゴリーに変えたら、別の情報が取得されたこともあった。
カテゴリーというのは、いわゆる音楽ジャンルのようなものだ。しかし、そんなものはCDには記録されていない。そこで、まずカテゴリーを取得する必要がある。それには、cddb queryコマンドを使う。
queryコマンドでカテゴリーを取得したら、今度はカテゴリーとディスクIDをパラメータとしてreadコマンドを使う。
これで、曲名を取得できる。
ただし、queryコマンドの結果が複数になることもあるので、注意が必要だ。その場合は、どれを採用するのかはプログラムで判断することは不可能だ。
人間が判断することになる。プログラムはその辺に対応しておく必要があるだろう。
では、コマンドの詳細を解説する。
●queryコマンド
必要な情報
A.discid
B.トラック数
C.各トラックの開始位置(フレーム単位)
D.全体の秒数
E.ユーザー名
F.サーバー名
G.システム名
H.システム名ver
I.仕様レベル
「全体の秒数」は端数をどうするのか気になるところだが、切り捨てで問題はない。というか、かなりずれていても認識するようだ。
E〜Hは適当で構わないようだ。
IはクライアントがFreeDBのどのバージョンに対応しているかを指定する。6以上でなければ日本語(UTF-8)が扱えない。
これらの情報から、次のような文字列を作る。
CMD=cddb+query+[discid]+[トラック数]+[開始位置1]+[開始位置2].....+[全体の秒数]
&hello=[ユーザー名]+[サーバー名]+[システム名]+[システムver]
&proto=[仕様レベル]
[]の文字はいれないこと。また、スペースの都合で改行しているが、実際は改行してはいけない。
ドキュメントには、POSTメソッドとGETメソッドのどちらでも使えるように書いてあるが(私の読み違いでなければだが)、
cddbwriteコマンド以外はGETメソッドしか使えないようだ。
試しに、Bon JoviのSlippery When Wetの情報を取ってみる。
●CDDB QUERYコマンドでカテゴリーを取得
http://www.freedb2.org/~cddb/cddb.cgi?cmd=cddb+query+7d0a510a+10+187+24530+41325+60887+79455+102592+121947+138482+158870+180642+2643&hello=joe+my.host.com+xmcd_via_email+v1.0&proto=1
*このコマンドで、カテゴリーがROCKだと判明する。
[結果]
200 rock 7d0a510a BON JOVI / Slippery When Wet
●CDDB READコマンドでCD情報を取得
http://www.freedb2.org/~cddb/cddb.cgi?cmd=cddb+read+rock+7d0a510a&hello=joe+my.host.com+xmcd_via_email+v1.0&proto=1
*このコマンドで、情報が取得できる。
なお、CDDB READの結果があれば、CDDB QUERYのコマンドを完成することができる。
この中には、CDDB QUERYコマンドに必要な情報が全て含まれているからだ。
戻る
トップへ