ホームに戻る
 WNASPI32.DLL と waveOutWrite でCD再生


cdplay (04/3/25 41.3kb/zip)


 このプログラムについて

CD-ROM をオーディオ再生するサンプルです。
特徴は WNASPI32.DLL と waveOutWrite による再生だということ。
どういうことかというと、
まずPCから CD-ROM ドライブを探し、
データを数値として読み込み、WAVE データとして再生します。
この方法のメリットはいったんデータをバッファに落とすので、
その間で波形の加工ができますし、細かな再生の制御もできます。
メリットは自由度が高い点。
デメリットは制御が難しい点。
実際に難しいので自分のコードも不安定で自信の無いものです。

技術的な部分の参考元はCマガジン2001年11月号です。
まず CD-ROM ドライブに関して、
PCにはATAPIなりSCSIなりで CD-ROM が繋がっていると思います。
まず「アダプター」という単位があります。
SCSIカード1枚でアダプター1つという感じです。
1アダプターにつきデバイスが8もしくは16扱えます。
8や16というのはバスの幅によるものです。
さらに1デバイスはLUNという単位を持ちます。
LUNは1ドライブに8つまで持てます。
LUNとは1ドライブが複数ドライブぶんの機能を持つときに、
機能を使い分けるために用いられる単位となります。
よって、1つの CD-ROM ドライブを扱うには、
どのアダプタで何番目のデバイスでどの番号のLUNか?
というのを取得してやらないといけません。
この情報を得るために用いられるWindows上の方法として、
WNASPI32.DLL を用いる方法があります。
WNASPI32.DLL のメインの関数は2つしかなくその辺は覚えやすい。
まずアダプタ数は以下の関数で得ます。

lpGetASPI32SupportInfo(void)

その他のコマンドはすべて以下の関数でOK。

lpSendASPI32Command(void *)

引数で渡すアドレスの構造体の要素によって目的の動作をさせます。
これで大抵の情報が取得できます。
まずはこの関数で CD-ROM ドライブの数や場所などの情報を取得。
複数ある場合はユーザーに選択させるなりして、
まずはどのアダプターで何番のデバイスでどのLUNかを定めます。

次に CD-ROM デバイス自体の情報や再生する CD の情報が要ります。
これも lpSendASPI32Command(void *) でできます。
CD-ROM はATAPIかSCSIか?の情報が要りますし、
CDはデータかオーディオか?ということも調べないといけません。
CDが入っていない場合のエラーの取得などもできます。

次に、データ自体を取ってくるわけですが、
CD-ROM は 2352 バイト単位でセクタと呼ぶらしく、
この単位で情報を取ってくることになります。
これも lpSendASPI32Command(void *) ですので、
情報を取ってきてバッファに収めたらこれを waveOutWrite です。
CD-ROM の音楽データはPCMのWAVE形式なので、
特に間で特別な変換の処理は要りません。
取得と再生は並行処理なのでスレッドなど用いることになります。

と、書いてきましたがだいぶ省略していますね。
詳しくはコードを見てください。
ソースファイルの構成はだいたい以下のようになっています。

main.cpp      : メインの流れとスレッド制御
main.h        : 全体的な設定に関する
s.cpp         : CD-ROM デバイスを探索
t.cpp         : CD-ROM の情報を取得
u.cpp         : CD-ROM のデータを読み込み
v.cpp         : WAVE 波形加工用
nmSound.cpp   : waveOutWrite での再生
nmSound.h     : 再生に関する

Borland C++ Compiler 用です。


補足(使い方)

command -d0 -t3

これでドライブ0の3曲目を再生します。
いちおう -h でヘルプがついています。
再生中は「now playing...」とでます。
エンターを押すと終了して「Finished」とでます。
どんな場合でも必ずエンターを押して Finished させて下さい。
あと免責としていかなるトラブルにも責任は負わないのはいつもの通りです。

inserted by FC2 system