MCIでのMIDIファイル再生について
MCIでのMIDIファイル再生について
タイトルにもあるとおり、MCIでMIDIファイルを再生することについてですが、なぜか僕の環境ではラグが起きています。
ラグが起きている間はフリーズしたようになります。なぜこのようになるのでしょうか。お答えお願いいたします。
-----僕の環境-----
WinXP Home Edition SP2
ActiveBasic Ver 4.01.02
ラグが起きている間はフリーズしたようになります。なぜこのようになるのでしょうか。お答えお願いいたします。
-----僕の環境-----
WinXP Home Edition SP2
ActiveBasic Ver 4.01.02
MCIでのMIDIファイル再生について
Windows2000/XPの仕様で、曲によっては10秒以上かかります。
のように、MPEGVideoデバイスを指定してやれば、すぐに再生されます。
Windows2000/XPであれば、MPEGVideoデバイスでMIDIを再生できますが、Windows95/98/Meの場合、MPEGVideoデバイスではMIDIなどを再生できない場合があります。その場合は普通に開きます。Windows95/98/Meなら普通に開いてもすぐ再生されるので、この方法はほぼ万能だと思います。
コード: 全て選択
'メッセージ通知のためのウィンドウを指定
mop.dwCallback=hMainWnd
'MPEGVideoデバイスを指定
mop.lpstrDeviceType = "MPEGVideo"
'MCIデバイスをオープン
bErr=mciSendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT _
or MCI_OPEN_TYPE,mop)
If bErr Then
'だめなら、MCI_OPEN_TYPEを消して再挑戦
bErr=mciSendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT ,mop)
If bErr Then
MessageBox(hMainWnd, _
"デバイスのオープンに失敗","error",MB_OK)
Exit Sub
End If
End If
Windows2000/XPであれば、MPEGVideoデバイスでMIDIを再生できますが、Windows95/98/Meの場合、MPEGVideoデバイスではMIDIなどを再生できない場合があります。その場合は普通に開きます。Windows95/98/Meなら普通に開いてもすぐ再生されるので、この方法はほぼ万能だと思います。
Re: MCIでのMIDIファイル再生について
返信ありがとうございます。コードを元にアレンジしてみました。
これでMCIファイルの再生もスムーズになりました。しかし、逆にwavファイルなどの時間をリストビュー化すると前のよりも時間がかかってしまいます。
どうすればいいでしょうか。
コード: 全て選択
Function OpenMciDevice(FileName As BytePtr) As Long
Dim bErr As DWord
Dim buffer[255] As Byte 'MCIエラーを格納する変数
'メッセージ通知のためのウィンドウを指定
mop.dwCallback=hMainWnd
'MPEGVideoデバイスを指定
mop.lpstrDeviceType = "MPEGVideo"
mop.lpstrElementName=FileName
'MCIデバイスをオープン
bErr=mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT or MCI_OPEN_TYPE, mop)
If bErr Then
'だめなら、MCI_OPEN_TYPEを消して再挑戦
mop.lpstrElementName=FileName
bErr=mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT ,mop)
If bErr Then
MessageBox(hMainWnd, "デバイスのオープンに失敗", "error", MB_OK)
OpenMciDevice=0
Exit Sub
End If
End If
OpenMciDevice=1
End Function
どうすればいいでしょうか。
Re: MCIでのMIDIファイル再生について
コード: 全て選択
'MPEGVideoデバイスを指定
mop.lpstrDeviceType = "MPEGVideo"
mop.lpstrElementName=FileName
再生しようとするメディアそれぞれにあったデバイスを選択すると
動作が速くなるでしょう。
そのためにはファイルの拡張子を調べて適切なデバイス名を
指定すればよいです。
(たぶんMCIに適切なデバイスを自動選択させているのが遅くなる原因だと思われます。)
代表的な拡張子とデバイスの対応
(この情報は[9X系ではwin.iniファイル][NT/XP系ではレジストリ]
[MEはwin.iniファイルとレジストリの両方]に入ってるみたいです。)
[mci extensions]
mid=Sequencer
rmi=Sequencer
wav=waveaudio
avi=AVIVideo
cda=CDAudio
midi=Sequencer
aif=MPEGVideo
aifc=MPEGVideo
aiff=MPEGVideo
asf=MPEGVideo2
asx=MPEGVideo2
au=MPEGVideo
snd=MPEGVideo
ivf=MPEGVideo2
m3u=MPEGVideo
mp3=MPEGVideo
mp2=MPEGVideo
mpa=MPEGVideo
mpe=MPEGVideo
mpeg=MPEGVideo
mpg=MPEGVideo
mpv2=MPEGVideo
mp2v=MPEGVideo
m1v=MPEGVideo
wax=MPEGVideo2
wvx=MPEGVideo2
wm=MPEGVideo2
wmx=MPEGVideo2
wma=MPEGVideo2
wmp=MPEGVideo2
wmv=MPEGVideo2
Re: MCIでのMIDIファイル再生について
またお答えありがとうございます。また修正しました。
以上のソースにしました。長ったらしいです^^;
しかし、なぜかMCIをオープンするときにエラーがでます。どこかいけないところでもあるでしょうか。
コード: 全て選択
Function OpenMciDevice(FileName As BytePtr) As Long
Dim bErr As DWord
Dim dwError As DWord
Dim buffer[255] As Byte 'MCIエラーを格納する変数
Dim OsVerInfo As OSVERSIONINFO 'OSのバージョンを格納する構造体
'メッセージ通知のためのウィンドウを指定
mop.dwCallback=hMainWnd
'OsVerInfo.dwOSVersionInfoSizeのサイズを指定
OsVerInfo.dwOSVersionInfoSize=Len(OsVerInfo)
'OSのバージョンを取得
GetVersionEx(OsVerInfo)
'もしOSがWin2KかWinXPでファイルがMIDIならMPEGVideoデバイスを指定
If OsVerInfo.dwPlatformId=VER_PLATFORM_WIN32_NT and OsVerInfo.dwMajorVersion=5 and OsVerInfo.dwMinorVersion=0 or OsVerInfo.dwMinorVersion=1 and Right$(FileName, 3)="mid" Then
mop.lpstrDeviceType="Sequencer"
mop.lpstrElementName="FileName"
bErr=mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT or MCI_OPEN_TYPE, mop)
If bErr Then
mciGetErrorString(dwError, buffer, 255)
MessageBox(hMainWnd, buffer, "デバイスのオープンに失敗 - error", MB_OK or MB_ICONERROR)
OpenMciDevice=0
Exit Sub
End If
Else
mop.lpstrElementName="FileName"
bErr=mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, mop)
If bErr Then
mciGetErrorString(dwError, buffer, 255)
MessageBox(hMainWnd, buffer, "デバイスのオープンに失敗 - error", MB_OK or MB_ICONERROR)
OpenMciDevice=0
Exit Sub
End If
End If
OpenMciDevice=1
End Function
しかし、なぜかMCIをオープンするときにエラーがでます。どこかいけないところでもあるでしょうか。
mop.lpstrElementName="FileName" でFileNameに 「""」がついているせいです。
あと、mid=Sequencerとありますが、これはOSのデフォルト設定で、MCI_OPEN_TYPEを使わなかったときに使う既定のデバイス名です。Sequencerでは、ラグがある状況に戻ります。ちゃんと"MPEGVideo"を指定してください。
また、OSの種類の判断についてですが、将来のバージョンのWindowsではMPEGVideoがサポートされない可能性があるし、2000/XPでも、MPEGVideoのサポート状況について、Microsoftから正式な資料はないので、従来どおり、bErrでの判定を推奨します。
あと、mid=Sequencerとありますが、これはOSのデフォルト設定で、MCI_OPEN_TYPEを使わなかったときに使う既定のデバイス名です。Sequencerでは、ラグがある状況に戻ります。ちゃんと"MPEGVideo"を指定してください。
また、OSの種類の判断についてですが、将来のバージョンのWindowsではMPEGVideoがサポートされない可能性があるし、2000/XPでも、MPEGVideoのサポート状況について、Microsoftから正式な資料はないので、従来どおり、bErrでの判定を推奨します。
> あと、mid=Sequencerとありますが、これはOSのデフォルト設定で、MCI_OPEN_TYPEを使わなかったときに使う既定のデバイス名です。
”Sequencer”はMCI_OPEN_TYPEを”使ったとき”に指定する値です。
但し、XPでは”ゲスト”の方が仰るように遅くなるようです。
MPEGVideoを指定することで早くなる理由はXPでプログラミングを始めたばかりの私にはよく分かりませんが、
私としては標準で定義されるデバイス名を指定するか、
最初からデバイス名を省略することを推奨します。
> また、OSの種類の判断についてですが、将来のバージョンのWindowsではMPEGVideoがサポートされない可能性があるし、2000/XPでも、MPEGVideoのサポート状況について、Microsoftから正式な資料はないので、従来どおり、bErrでの判定を推奨します。
確か、MCI_SYSINFOコマンドでデバイス対応状況を取得出来た筈です。
それについて場合分けをすればよいでしょう。
それにしてもMCIは奥が深いな。。。
”Sequencer”はMCI_OPEN_TYPEを”使ったとき”に指定する値です。
但し、XPでは”ゲスト”の方が仰るように遅くなるようです。
MPEGVideoを指定することで早くなる理由はXPでプログラミングを始めたばかりの私にはよく分かりませんが、
私としては標準で定義されるデバイス名を指定するか、
最初からデバイス名を省略することを推奨します。
> また、OSの種類の判断についてですが、将来のバージョンのWindowsではMPEGVideoがサポートされない可能性があるし、2000/XPでも、MPEGVideoのサポート状況について、Microsoftから正式な資料はないので、従来どおり、bErrでの判定を推奨します。
確か、MCI_SYSINFOコマンドでデバイス対応状況を取得出来た筈です。
それについて場合分けをすればよいでしょう。
それにしてもMCIは奥が深いな。。。
> 但し、XPでは”ゲスト”の方が仰るように遅くなるようです。
もしかしたら9XとかMEでもMPEGVideoで早くなるかもしれませんね。
> MPEGVideoを指定することで早くなる理由はXPでプログラミングを始めたばかりの私にはよく分かりませんが、
さっそく理由を調べてきました。
MPEGVideoのドライバがmidとwavの両方に対応していることが多いと
いうことらしいです。
このMPEGVideowoをwavやmidの再生に使用すると再生開始時間が早くなる
以外にも再生速度を変えることができたり、
ループ再生の速度が速くなったりという恩恵があるようです。
※MPEGVideoのドライバによるとmidに対応していない場合があるようです。
MPEGVideo2の方が確実性が高いらしいけど、こっちが搭載されているほうが確実性が低いような気がします。
もしかしたら9XとかMEでもMPEGVideoで早くなるかもしれませんね。
> MPEGVideoを指定することで早くなる理由はXPでプログラミングを始めたばかりの私にはよく分かりませんが、
さっそく理由を調べてきました。
MPEGVideoのドライバがmidとwavの両方に対応していることが多いと
いうことらしいです。
このMPEGVideowoをwavやmidの再生に使用すると再生開始時間が早くなる
以外にも再生速度を変えることができたり、
ループ再生の速度が速くなったりという恩恵があるようです。
※MPEGVideoのドライバによるとmidに対応していない場合があるようです。
MPEGVideo2の方が確実性が高いらしいけど、こっちが搭載されているほうが確実性が低いような気がします。
ありがとうございます
> また、OSの種類の判断についてですが、将来のバージョンのWindowsではMPEGVideoがサポートされない可能性があるし、2000/XPでも、MPEGVideoのサポート状況について、Microsoftから正式な資料はないので、従来どおり、bErrでの判定を推奨します。
次世代のWindowsはロングホーンということらしいですが、今のところかなり先のことなのですので、そのことについては考えていません。また、もしMPEGVideo=MPEG1ということなら、MPEG1のコーデックは全てのWindowsに搭載されているはずですので。
> 確か、MCI_SYSINFOコマンドでデバイス対応状況を取得出来た筈です。それについて場合分けをすればよいでしょう。
MCI_SYSINFOコマンドってどのように使うのでしょうか...。
とりやえず修正してみました。
以上です。
次世代のWindowsはロングホーンということらしいですが、今のところかなり先のことなのですので、そのことについては考えていません。また、もしMPEGVideo=MPEG1ということなら、MPEG1のコーデックは全てのWindowsに搭載されているはずですので。
> 確か、MCI_SYSINFOコマンドでデバイス対応状況を取得出来た筈です。それについて場合分けをすればよいでしょう。
MCI_SYSINFOコマンドってどのように使うのでしょうか...。
とりやえず修正してみました。
コード: 全て選択
'MCIデバイスをオープンする為の自作関数。
Function OpenMciDevice(FileName As BytePtr) As Long
Dim bErr As DWord
Dim dwError As DWord
Dim buffer[255] As Byte 'MCIエラーを格納する変数
Dim OsVerInfo As OSVERSIONINFO 'OSのバージョンを格納する構造体
'メッセージ通知のためのウィンドウを指定
mop.dwCallback=hMainWnd
'OsVerInfo.dwOSVersionInfoSizeのサイズを指定
OsVerInfo.dwOSVersionInfoSize=Len(OsVerInfo)
'OSのバージョンを取得
GetVersionEx(OsVerInfo)
'もしOSがWin2KかWinXPでファイルがMIDIならMPEGVideoデバイスを指定
If OsVerInfo.dwPlatformId=VER_PLATFORM_WIN32_NT and Right$(FileName, 3)="mid" Then
If OsVerInfo.dwMinorVersion=0 or OsVerInfo.dwMinorVersion=1 Then
mop.lpstrDeviceType="MPEGVideo"
mop.lpstrElementName=FileName
bErr=mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT or MCI_OPEN_TYPE, mop)
If bErr Then
mciGetErrorString(dwError, buffer, 255)
MessageBox(hMainWnd, buffer, "SameFolder MusicPlayer Error", MB_OK or MB_ICONERROR)
OpenMciDevice=0
CloseMciDevice()
Exit Sub
End If
End If
Else
mop.lpstrElementName=FileName
bErr=mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, mop)
If bErr Then
mciGetErrorString(dwError, buffer, 255)
MessageBox(hMainWnd, buffer, "SameFolder MusicPlayer Error", MB_OK or MB_ICONERROR)
OpenMciDevice=0
CloseMciDevice()
Exit Sub
End If
End If
OpenMciDevice=1
End Function
Re: ありがとうございます
>
> MCI_SYSINFOコマンドってどのように使うのでしょうか...。
>
残念ながら私も分かりません。mciSendStringの方なら分かるんですが。。。
> MCI_SYSINFOコマンドってどのように使うのでしょうか...。
>
残念ながら私も分かりません。mciSendStringの方なら分かるんですが。。。
コード: 全て選択
#N88BASIC
#include <api_mmsysPro4.sbp>
Dim buf[255] As Char
Dim DeviceNum As Long
mciSendString("sysinfo all quantity",buf,256,NULL)
DeviceNum=Val(buf)
Dim cnt As Long
For cnt=1 To DeviceNum
mciSendString("sysinfo all name "+Str$(cnt),buf,256,NULL)
Print MakeStr(buf)
Next