ご無沙汰してます。未だにVer3を使っているSunshineです。
今、ゲームに音楽をつけたいと思っています。mciSendString関数を使い、音楽のループ再生を作ってみました。
ゲームとウィンドウは別スレッドで実現したほうが良いと思い、どうせなら音楽も別スレッドを……、という考えから、別スレッドでMCIを使うことにしました。
で、使ってみたのですが、音が途中で途切れてしまいます。ループ内のmciSendStringの処理のせいだろうと思うのですが、どうにか音を途切れさせずに音楽を流すにはどうすればよいのでしょうか。
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (lpstrCommand As BytePtr, lpstrReturnString As BytePtr, uReturnLength As Long, hwndCallback As Long) As Long
Dim hMainThread As DWord
Const FILE = "test.mid"
Const POSITION = "11500" '再生開始位置11.5秒
Sub Main()
Dim retBuffer[19] As Byte
mciSendString("open "+FILE+" type sequencer alias Music", 0, 0, 0)
mciSendString("set Music time format ms", 0, 0, 0)
mciSendString("play Music wait", 0, 0, 0)
Do
mciSendString("play Music from "+POSITION+" wait", 0, 0, 0)
Loop
End Sub
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
TerminateThread(hMainThread, 0)
CloseHandle(hMainThread)
mciSendString("close all", 0, 0, 0)
Player_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
Dim dwDummy As DWord
hMainThread = CreateThread(ByVal 0,0,AddressOf(Main),0,0,VarPtr(dwDummy))
End Sub
音楽…
うーんと、根本的な解決になってないかもしれませんが、
いつも私が使う手法をば。
私の場合はSetTimer使います。少々長くなりますが
いつも私が使う手法をば。
私の場合はSetTimer使います。少々長くなりますが
コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシ?#91;ジャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコ?#91;ディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグロ?#91;バルな変数、構造体、定数、関数を定義します。
'-----------------------------------------------------------------------------
' ウィンドウメッセ?#91;ジを処理するためのコ?#91;ルバック関数
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセ?#91;ジを処理するためのコ?#91;ドを記述します。
' イベントプロシ?#91;ジャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシ?#91;ジャを記述するための領域になります。
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
Sub MainWnd_Destroy()
KillTimer(hMainWnd, 100) '終了時にキルタイ?#125;
mciSendString("close Media", buf, 255, 0) 'クロ?#91;ズ
daisdhas_DestroyObjects()
PostQuitMessage(0)
End Sub
Dim fname As String
Dim buf As String 'mciSendStringの戻りバッファ用
Dim mlen As Long
Sub MainWnd_CommandButton1_Click()
fname=Ex"\qC:\\Test.mpg\q" '\qでくくることでスペ?#91;スのあるパスも再生可能
buf = ZeroString(255)
mciSendString("open " & fname & " type mpegvideo alias Media", buf, 255, 0) 'mpegvideoと指定することで、拡張子偽装のファイルも再生可能です。
mciSendString("set Media time format ms", buf, 255, 0)
mciSendString("status Media length", buf, 255, 0)
mlen = Val(buf) '全体の長さを取得
mciSendString("play Media", buf, 255, 0)
SetTimer(hMainWnd, 100, 1, NULL) 'タイ?#125;設定
End Sub
Sub MainWnd_Timer(ByVal TimerID As Long)
If TimerID = 100 Then
mciSendString("status Media position", buf, 255, 0)
If Val(buf) >= mlen Then mciSendString("play Media from 0", buf, 255, 0) '現在時間が全体時間以上になったらル?#91;プ
End If
End Sub