Visual Basic 6.0 テクニック |
Visual Basic 中学校 > VB6 テクニック >
1.VBでサウンドを再生する方法
ここではVBでサウンドを再生する方法の一つを説明します。
ここで対象となるサウンドとはファイルの拡張子が .mid .wav . mp2 .mp3 の形式である物を指します。
この回の要約
Call mciSendString("play """ & FILE_NAME & """", "", 0, 0)
|
1.方法論
VBの機能としてはサウンド再生の機能はほとんど提供されていません。一応 Beep や MsgBox で音は鳴らせますが「サウンド」という点からは不満山積です。そこで、この他にVBからサウンドを再生するのにどういう方法があるか表にまとめてみました。
方法 | メリット | デメリット |
APIを使う |
|
|
ActiveXを使う |
|
|
DirectXを使う |
|
|
■表1:VBからサウンドを再生する方法
「DirectXを使う」というのも「ActiveXを使う」の一種なのですがここでは別項目にまとめてみました。念のために確認しておくとActiveXというのはVBの機能を拡張できる便利なソフトのことです。たとえば、Windowsに付属しているMediaPlayerはActiveXとしてVBから使用することもできるのです。
このようなActiveXは店で売っているものもあるし、Webでフリーウェアやシェアウェアとして公開されているものもありますから使いこなせば何かと便利です。サウンド再生機能があるActiveXで有名なものはMediaPlayerの他にMMControlがあります。MMControlはVBのProfessionalEdition以上に付属していますが現在ではあまり使われていないようですね。
今回は、「どの環境でも使用できる」方がこの記事を読んでいる皆さんの役に立てると思いますのでAPIを使う方法を説明します。
2.手っ取り早い方法
早く結論を知りたい方のために、さっそくサウンドを演奏するサンプルを載せます。
コントロール | 種類 | 機能 |
Command1 | CommandButton | サウンドを再生する |
Command2 | CommandButton | サウンドの再生を停止する |
■表2
Private Declare
Function mciSendString Lib "winmm.dll"
Alias "mciSendStringA" (ByVal
lpstrCommand As String,
ByVal lpstrReturnString As String,
ByVal uReturnLength As
Long, ByVal hwndCallback
As Long) As Long Private Const FILE_NAME As String = "C:\Test.mp3" |
Private Sub
Command1_Click() Call mciSendString("play """ & FILE_NAME & """", "", 0, 0) End Sub |
Private Sub Command2_Click() Call mciSendString("close """ & FILE_NAME & """", "", 0, 0) End Sub |
■サンプル1:サウンドの再生と停止
このサンプルは C:\Test.mp3 を再生・停止します。ここではmp3を指定していますが、wav、mid、mp2を指定しても正しく再生できます。
しかし問題があります。実はこの方法ではmp3が再生できない環境があるのです。私も詳しいことは分からないのですが多分Windows98 + MediaPlayer 6.4より古い環境ではこの方法ではmp3は再生できないでしょう。wavやmid、mp2は再生できます。Windows 2000以上の環境ならば問題ないと思います。古い環境でmp3を再生したい場合はテクニック 第2回を参考にしてください。
3.使うAPIは一つだけ
さて、サンプル1からも分かるように使うAPIはmciSendStringの一つだけです。その宣言は次の通りです。
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long |
■サンプル2:mciSendString関数の宣言
この関数は奥が深いので詳しい説明はMSDN Library等を参照してください。ここではあくまでも簡単にできる範囲のことを説明します。
このAPI関数は第一引数 が最も重要です。この引数だけで再生したり停止したりを指示します。あとの引数はサンプル1では簡単に設定してしまいましたが、後で少しだけ説明します。
4.工夫する
プログラムを分かりやすくするために少し加工してみましょう。mciSendString関数を利用してサウンドファイルを再生する関数と再生を停止する関数を作ってみます。
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long |
Private Sub PlaySound(FileName
As String) Call mciSendString("play """ & FileName & """", "", 0, 0) End Sub |
Private Sub StopSound(FileName
As String) Call mciSendString("close """ & FileName & """", "", 0, 0) End Sub |
■サンプル3:サウンドの再生と停止
これであなたはmp3, mp2, wav, midを自由に再生したり停止したりできるようになりました。なんて素敵なんでしょう。
5.でもこれ低機能
しかし再生と停止だけできれば良いのでしょうか。もう少し欲張っていろいろな機能をつけてみたいと思いませんか。mciSendString関数を使えばもっといろいろなことができるし、実際そのうちのいくつかはとても簡単です。
たとえば一時停止する機能を追加するには次のような関数をつくるだけです。
Private Sub PauseSound(FileName
As String) Call mciSendString("pause """ & FileName & """", "", 0, 0) End Sub |
■サンプル4:サウンドの一時停止
続きから再生するにはmp3の場合、前のサンプル3にあるPlaySound関数を実行するだけなのですがwavの場合にはPlaySound関数を実行するとまた最初からになってしまいます。どうしてこんな違いがあるのかはわかりません。
正式には続きから生成するには次のようにするらしく、この方法ならmp3でもwavでもいけます。
Private Sub ResumeSound(FileName
As String) Call mciSendString("resume """ & FileName & """", "", 0, 0) End Sub |
■サンプル5:一時停止の続きから再生
とことで、再生・停止・一時停止・続きから再生のどれもほとんどプログラムは一緒ですよね。違うのはmciSendString関数の第1引数だけです。
ここまで理解するとmciSendString関数の第1引数、つまりMCIコマンド文字列が重要だということがわかってくると思います。何をするにもMCIコマンド文字列を使わなければなりません。
MCIコマンド文字列情報は以下のサイトにあります。
しかし難解です。英語で書いてあるうえにある程度マルチメディアとC++の知識がなければ理解できません。だいたいこれを読んで分かる人はこのページの説明を読む必要はありません。
次からは私がこのサイトから解読できたいくつかの機能を説明しましょう。
6.時間を取得する
音楽の長さを時間単位で取得する方法を説明しましょう。もちろんMCIコマンド文字列を使うのですが今までとの大きな違いは、「取得する」という点です。今までの再生・停止・一時停止は命令したらしっぱなしでこちらが情報を取得することはありませんでした。
情報を取得するにはmciSendString関数の第2、第3引数を使います。ここでもこれらを呼び出しやすいように次のような関数にまとめてみましょう。
'■ファイルの長さを秒単位で返す。 Private Function GetLength(FileName As String) As Double Dim RetBuffer As String * 20 Dim MCICommandString As String MCICommandString = "status """ & FileName & """ length"
Call mciSendString("open """ & FileName & """", "", 0, 0) |
■サンプル6:長さの取得
このように情報を要求した場合、mciSendString関数は第2引数に回答を返してきます。また第3引数には第2引数の長さを渡しておく必要があります。
そして、ファイルの長さを取得するためのMCIコマンド文字列は 「status ファイル名 length」というわけです。 また開いていないファイルの長さは取得できない場合があるので長さを取得する前後にopenとcloseも入れています。
こうやって説明しているとあまり難しく思えないかもしれませんが、上記のリンクからこの情報を見つけ出すのはちょっと骨が折れました。
ところで実はこの関数には問題があります。対象がmp3やwavの時には正しく長さを取得できるのですがmidの時にはどうも妙な値が返ってきてしまいます。
いろいろ考えたのですがどうもよくわかりません。midの場合には別にテンポの取得して、計算しなければいけないのだと思います。テンポを取得するにはMCIコマンド文字列に「status ファイル名 tempo」と記述します。midの長さの取得方法が分かる方は是非教えてください。
7.現在位置を取得する
再生中に現在再生中の位置を取得するにはMCIコマンド文字列に「status ファイル名 position」を指定します。
これを利用して再生中のファイルの現在位置を取得するコードは次のようになります。
'■再生中のファイルの位置を秒単位で返す。 Private Function GetPosition(FileName As String) As Double Dim RetBuffer As String * 20 Dim MCICommandString As String MCICommandString = "status """ & FileName & """ position" Call mciSendString(MCICommandString, RetBuffer, Len(RetBuffer), 0) GetPosition = Val(RetBuffer) / 1000 End Function |
■サンプル7:現在位置の取得
MCIコマンド文字列が変わるだけなのでサンプル6(長さの取得)とほとんど同じです。現在位置がわかれば多くのサウンドプレイヤーがやっているように再生に合わせてスライダーを動かしたりできるようになります。
なお、これも開いていないファイルだと失敗することがあるらしいのですが、「現在位置を取得する」という性質上ファイルは既に開かれているはずですのでファイルを開くopenは記述していません。
8.現在位置をセットする
自分で位置をセットして、途中から再生することもできます。これは「seek ファイル名 to 位置」という形でMCIコマンド文字列を指定します。位置はミリ秒単位の数値で指定します。なお、seekを使用すると再生中のサウンドは停止してしまいますので、seek後にもう一度playを使います。
'■再生位置を秒単位で指定する。 Private Sub SetPosition(FileName As String, Position As Double) Dim NewPosition As Long NewPosition = Position * 1000 Call mciSendString("seek """ & FileName & """ to " & NewPosition, "", 0, 0) Call mciSendString("play """ & FileName & """", "", 0, 0) End Sub |
■サンプル8:再生位置の指定
9.繰り返し再生
私の調べた範囲ではMCIコマンド文字列を使って繰り返し再生を指示することはできません。しかし、自分でプログラムすることで繰り返し再生を実現することができます。
繰り返し再生とは、「もし、再生が終了しているなら、初めに戻って、再生せよ。」ということなので現在「再生中」 なのか「停止中」なのか判断できれば自分で繰り返して再生するように命令することができるということです。
そして現在の状態はMCIコマンド文字列を使って「status ファイル名 mode」のようにすることで取得できます。このコマンドを使用すると、mciSendString関数は第2引数に、再生中のとき"Playing"、停止中のとき"Stopped"、一時停止中のとき"Paused"を返してきます。この他にも"not ready"(準備が完了していない?)、"open"(開いている?), "parked"(停止している?), "recording"(録音中?), "seeking"(探索中?)などの値が用意されているようですが、私はであったことがないので詳細はわかりません。
以上を踏まえて「まず、現在の状態を返す関数を作って、タイマーで定期的にそれを呼び出し、現在の状態が停止中ならもう一度再生させる」という流れで繰り返し再生を実現させましょう。プログラムは次のようになります。
Private Const FILE_NAME As String = "C:\Test.mp3" |
Private Sub Command1_Click() Call PlaySound(FILE_NAME) Timer1.Interval = 100 Timer1.Enabled = True End Sub |
Private Sub
Timer1_Timer()
If GetSoundStatus(FILE_NAME) = "STOPPED" Then Call StopSound(FILE_NAME) Call PlaySound(FILE_NAME) End If End Sub |
Private Function GetSoundStatus(ByVal FileName As String) As String Dim RetBuffer As String Dim MCICommandString As String RetBuffer = Space(20) MCICommandString = "status """ & FileName & """ mode" Call mciSendString(MCICommandString, RetBuffer, Len(RetBuffer), 0) RetBuffer = Left(RetBuffer, InStr(1, RetBuffer, vbNullChar) - 1) GetSoundStatus = UCase(RetBuffer) End Function |
■サンプル9:繰り返し再生
10.最後に
以上説明してきた技術を使って簡単なサウンドプレイヤーのサンプルを作ってみました。よろしかったらダウンロードしてみてください。
ダウンロード 4.0KB lha形式(拡張子はlzh)
主な機能:再生、一時停止、一時停止の続きから再生、停止、長さの取得、現在位置の取得、再生位置の指定、繰り返し再生、状態の取得
このプレイヤーではmp3、wav、mid、mp2の再生の制御ができますがはっきりいってWindows Media Playerに比べたら天と地です。それにmidとmp2は一部の機能が利用できません。あくまでプログラムする参考のためのものと思ってください。そのためユーザーインターフェイスまわりはあまり細かい点に気を配っていません。
ところで、この第1回は何年か前に一度書いたのを今回久しぶりに全面改訂したものです。同時は私はWindows98 + Media Player 6.4でしたが、今はWindows XP + Media Player 9 です。そして、改訂前このページの最後にはこう書いていてありました。
「実はこのAPIではMP3を再生できません。(Windowsのバージョンがあがればできるようになると期待しますが)。」
期待があたって今ではMp3も再生できるようになりましたね。うれしい限りです。これからも科学の発展は私たちの夢をかなえてくれるでしょう。
今回の重要単語
重要単語 | 読み方 | 説明 |
close | クローズ | MCIコマンド文字列の一つ。ファイルを閉じて再生を終了する。 |
length | レンクス | MCIコマンド文字列の一つ。statusとともに用いファイルの長さを取得する。 |
mciSendString | エムシーアイセンドストリング | サウンドをはじめ映像などのメディアファイルを制御するためのWindows API関数。MCIコマンド文字列を使ってメディアを制御する。 |
mode | モード | MCIコマンド文字列の一つ。statusとともに用いファイルの状態を取得する。 |
open | オープン | MCIコマンド文字列の一つ。ファイルを開く。 |
pause | ポーズ | MCIコマンド文字列の一つ。ファイルを一時停止する。 |
play | プレイ | MCIコマンド文字列の一つ。ファイルを再生する。 |
position | ポジション | MCIコマンド文字列の一つ。statusとともに用いファイルの現在位置を取得する。 |
resume | リジューム | MCIコマンド文字列の一つ。一時停止状態から再生を続行する。 |
seek | シーク | MCIコマンド文字列の一つ。ファイルを再生位置を指定する。 |
status | ステータス | MCIコマンド文字列の一つ。ファイルに関する情報を取得する。 |
MCIコマンド文字列 | エムシーアイコマンドもじれつ | マルチメディアを制御するためのスクリプト?マルティメディアコマンド文字列ともいうらしい。 詳細は次のページ |
■表3:今回の重要単語