• ベストアンサー

windows API  「mciSendString」 の連続再生について

VISUAL BASIC 6.0 で音楽再生ソフトを作ろうとしました。 windows API の「mciSendString」を使って、 例1のようにすると b.wav の音楽しか再生されません。 そこで、例2のようにすると、a.wav と b.wav が再生されましたが、 曲の途中では、"pause" と "resume" の命令が効きません。 連続再生ができて、曲の途中でも "pause" や "resume" の命令が効く方法を知りたいのですが、ご指導をお願いします。 <例1> Call mciSendString("open c:\a.wav ", "", 0, 0) Call mciSendString("play c:\a.wav ", "", 0, 0) Call mciSendString("close c:\a.wav ", "", 0, 0) Call mciSendString("open c:\b.wav ", "", 0, 0) Call mciSendString("play c:\b.wav ", "", 0, 0) Call mciSendString("close c:\b.wav ", "", 0, 0) <例2> Call mciSendString("open c:\a.wav ", "", 0, 0) Call mciSendString("play c:\a.wav wait ", "", 0, 0) Call mciSendString("close c:\a.wav ", "", 0, 0) Call mciSendString("open c:\b.wav ", "", 0, 0) Call mciSendString("play c:\b.wav wait ", "", 0, 0) Call mciSendString("close c:\b.wav ", "", 0, 0)

質問者が選んだベストアンサー

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.4

> 具体的にイベント取得関数とはどのようなものでしょうか。 MCI へ Notify オプション付きのコマンドを渡して、コールバックされた終了 メッセージを受け取る...ということです。それしかないと思いますよ。 #2 の参考 URL にこのことが書いてあります。MCI を使った例でコールバック のサンプルプロシージャも同サイトに記事がありますし... http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/subc/ とりあえず、読んでみましょうよ。 ただ、#3 の方もコメントされてますが、VB ではサブクラス化という特殊な 技法が必要です。うっかりデバッグモードでプログラムを停止したりすると OS ごとフリーズしますので、難易度は非常に高いです。

peace108
質問者

お礼

丁寧な回答有り難うございます。 Notify オプション付きのコマンドを用いて、Doneイベントで対処したらうまくいきました。 又、timerコントロール内で演奏残時間が0になったら、次の曲へ移るSubプロシージャを呼ぶ出すプログラムを当初作っていてうまく動作しませんでしたが、再度チェックしたら、間違い箇所が見つかり、このプログラムもうまく動くようになりました。 色々お騒がせをし申し訳ありませんでした。

その他の回答 (3)

  • PED02744
  • ベストアンサー率40% (157/390)
回答No.3

すでにANo.2の方がとても参考になるURLを示されているので、意味なくなったんですが(笑) 基本的に、mciは GDIコントロールとして存在するので、VBからは限界があるのです。 おそらく、曲が終わったら次の曲へ。。としたいのだと思いますが、 これがCDのようにトラックになっている場合ならVBだけでできるんですが、 質問されているような、自作のwave形式のファイルの羅列のような場合は、 getYield/setYieldでイベント取得関数を作って、曲の終了を受け取って 次の曲へ移動するような仕組みが必要です。 でも、VBでは受け取る関数(コールバック)を作るのは、そうとう難易度高いと思います。 ANo.2さんの示されたURLからたどれば、可能な方法にたどりつけるようですので、がんばってみられてもよいかとおもいます。

peace108
質問者

お礼

1)[Timer]コントロールを用いて、 [mcisendstring]の”status”コマンドで、曲終了時の「STOPPED」という戻り値が来たら(又は残演奏時間が0になった時)次の曲に行くようにプログラムを既に組んでいました。2曲目が長い曲であれば、次の曲がPlayできるのですが、2曲目が1曲目より演奏時間が短いと、次の曲がplayできずに、ストップされたままでした。なぜかよくわからず、今回の質問に至りました。曲の演奏時間の長短でPlayできない理由がよくわかりません。 2)「getYield/setYieldでイベント取得関数を作って、曲の終了を受け取って次の曲へ移動するような仕組みが必要です。」とありますが、具体的にイベント取得関数とはどのようなものでしょうか。 [mcisendstring]の”status”コマンドでよろしいのでしょうか。

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.2

この記事も参考になりますよ。 ・[VB Magazine ライブラリ]  マルチメディア自由自在! 高レベルMCIを使う  http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/mci/

参考URL:
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/mci/
回答No.1

お世話になります。 こちらは、もうご覧になりましたか? http://homepage1.nifty.com/rucio/main/dotnet/Samples151/Sample187PauseSound.htm

関連するQ&A

  • C# MciSendStringでのMP3再生

    お世話になります。 MciSendStringを使用して、MP3を再生、停止する方法に、 stopをして、再びplayさせる方法と、pauseをかけてresumeで 再び再生させる方法の二種類がありますが、この二つの 明確な違いはあるのでしょうか。 もし違いがないのであれば、playとstopだけで事足りて しまうような気がするのですが、どうなのでしょうか。 大きな違いがあるようでしたら、教えてください。 よろしくお願いいたします。

  • オーディオサンプルレートの変更

    皆様のお力をお貸しください。 【環境】 OS:Windows XP 開発環境:VB6.0 現在WAVファイル(16bit,22KHz)のファイルを 16bit 8KHzに変換するものを上記環境にて作成使用としていますが ネット上を検索しても該当するような情報を検索できませんでしたので質問させていただきます。 以下のような手順にてWAVファイルを再生させることはできましたが サンプルレートの変更を行うことはできませんでした。 Call mciSendString("open " + 変換元ファイル名称 + " alias f", "", 0, 0) Call mciSendString("play f", "", 0, 0) Call mciSendString("set f bitspersample 16", "", 0, 0) Call mciSendString("set f samplespersec 8000", "", 0, 0) Call mciSendString("save f " & 変換後ファイル名称, "", 0, 0) Call mciSendString("close f", "", 0, 0) このような単純なことではなく、もっと複雑な処理を検討しないと ならないものでしょうか。 別な方法にてできるものがありましたら、教えてください。 よろしくお願いいたします。

  • midi再生について

    visual basicを使ってゲームを作成しております。 あるサイトを見てmidiの再生をやってみようと下記のコードを入力しました。 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 Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMillsecounds As Long) Sub MCI_Test() Dim P As String, filename As String filename = "sample.mid" P = """" & ActiveWorkbook.Path & "\" & filename & """" Call mciSendString("open " & P & " alias sample", vbNullString, 0, 0) DoEvents Call mciSendString("play sample from 0", vbNullString, 0, 0) Call Sleep(10000) Call mciSendString("close sample", vbNullString, 0, 0) End Sub このコードでfilenameの部分を変更しwavファイルのsample.wavやMP3ファイルのsample.mp3は再生する事ができました。しかし、midiファイルはsample.midを同じフォルダ内に入れているにも関わらず全く音が鳴りません。どこが間違っているのでしょうか。教えてください。宜しくお願い致します。

  • API 録音 MCI

    C#を勉強しております。 現在マイクから録音音声を読み取りファイルとして保存するプログラムを組んでいます。 [DllImport("winmm.dll")] extern static int mciSendString(string s1, StringBuilder s2, int i1, int i2); strSetup = "channels 2 samplespersec 44100 bytespersec 176400 alignment 4 bitspersample 16"; private void button1_Click(object sender, EventArgs e) { mciSendString("open new type waveaudio alias Rec", null, 0, 0); mciSendString("set Rec " + strSetup, null, 0, 0); mciSendString("record Rec", null, 0, 0); } string strFilename = "C:\\test.wav"; private void button2_Click(object sender, EventArgs e) { mciSendString("stop Rec", null, 0, 0); mciSendString("save Rec " + strFilename, null, 0, 0); mciSendString("close Rec", null, 0, 0); } とこんな感じにしてみたのですがファイルができる気配がありません。 どこがまずいのでしょうか?

  • EXCEL VBA でAPIを使って

    EXCEL VBA でAPIを使って音源を再生しているのですが、すぐに再生されるときと、再生されるまでに3秒くらいかかるときがあるのですが、なぜでしょうか? 音源の再生のコードは下記のとおりです。 Call mciSendString("Play " & FILE_NAME1, "", 0, 0) 素人の質問で申し訳ありませんが、どなたか解決方法を教えてください。

  • vb6.0でwavファイルの終了を監視する方法について

    お世話になります。 vb6.0でwavファイルを再生するプログラムを作成しております。 下記にコードを記述させていただきます。 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 MSComm1_OnComm() '演奏が終了しているか確認 If LCase$(Left$(mciSendString("Status MIDI1 mode", "", 0, 0), 7)) = "stopped" Or _ LCase$(Left$(mciSendString("Status MIDI1 mode", "", 0, 0), 7)) = "0" Then ←(1) Dim ret As Long ret = mciSendString("stop midifile ", "", 0, 0) ret = mciSendString("close midifile", "", 0, 0) ret = mciSendString("open """ & P_PLIST_WARNING & """", "", 0, 0) ret = mciSendString("play """ & P_PLIST_WARNING & """ from 0 wait", "", 0, 0) ret = mciSendString("stop """ & P_PLIST_WARNING & """", "", 0, 0) ret = mciSendString("close """ & P_PLIST_WARNING & """", "", 0, 0) End If End Sub wavファイルを再生するにあたり、まず再生されていない状態を確認してから、再生したいと考えています。 しかしながら、(1)のコードで戻り値が"stopped"または"0"ではなく、"263"で返ってきており、停止を監視できず困っております。 お手数ですが、ご教授いただきたく宜しくお願い申し上げます。

  • vbsでwavを連続(繰り返し)再生させるには?

    vbsでメッセージと共にwavファイルをsndrec32(サウンドレコーダ)で警告音を鳴らしたいのですが、 strSoundFile="C:\WINNT\Media\×××.wav" Set objShell=CreateObject("Wscript.Shell") strCommand="sndrec32 /play /close" & chr(34) & strSoundFile & chr(34) objShell.Run strCommand, 0, False Msgbox "警告" 上記のソースだとwavファイルが一回再生されるだけなのですが、メッセジボックスのOKを答えるまで繰り返し再生させるにはどうしたら良いのでしょうか?

  • VBAのwav操作ついて!!

    エクセルのVBAでプログラムを作っているのですが、wavを操作することに関してわからないことがあります。 (general)に -------------------------------------------------------- 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 FILE001_NAME As String = "C:\001.wav" Private Const FILE002_NAME As String = "C:\002.wav" ・・・ ------------------------------------------------------- というのを入れていまして、音を出したいところで Call mciSendString("play """ & FILE○_NAME & """", "", 0, 0) という方式でwavを再生させようと思っています。 ここで、FILEのあとをワークシート1上のA1セル上の数字に変えたいと思います。つまり、A1セル内の数(乱数で1~100のいずれかを表示させています)を○のところに入れるにはどうすればいいでしょうか? どなたかおわかりになる方、教えてください。お願いいたします。

  • midiの再生が思うようにできません

    ファイルの文字列を1行ずつ読み込み、文字列の数字の範囲によって再生する音楽を変えるプログラムを作成していますが、読み込んだ文字列とは無関係に、ループの初めの範囲で指定してある音楽しか再生されません。読み込んだ文字列ごとに再生音楽を変えるにはどうすればいいのでしょうか?分かる方ご教授願います。 環境:WindowsXP, Visual C++ 2008 Express Edition 以下がプログラムのソースの一部です。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { FILE *fp; errno_t err; TCHAR buf[30]; TCHAR *temp; int m=0, n=0; switch(msg) { case WM_CREATE: CreateWindow(TEXT("BUTTON"), TEXT("Play"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,120, 100, 70, 70, hWnd, NULL, hInst, NULL); break; case WM_COMMAND: err = _tfopen_s(&fp, TEXT("C:\\Documents and Settings\\m22015\\My Documents\\Visual Studio 2008\\Projects\\process\\process\\Corner.txt"), TEXT("r+")); if(err != 0) break; temp = (TCHAR*)malloc(_tcsclen(buf)+1); if(temp == NULL){ MessageBox(hWnd, TEXT("Can't secure of memory"), TEXT("Error"), MB_OK); break; } for(int i=0; i<2; i++){ _fgetts(buf, 10, fp); _tcstok(buf, TEXT("\n")); } while(_fgetts(buf, 30, fp) != NULL){ _tcstok(buf, TEXT("\n")); _tcscpy(temp, buf); while(_stprintf(buf, _T("- { x:%d, y:%d }"), m, n)!=EOF){ if((m>=0 && m<110)&&(n>=0 && n<200)){ if(mciSendString(_T("play C+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play C+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=110 && m<220)&&(n>=0 && n<200)){ if(mciSendString(_T("play D+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play D+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=220 && m<330)&&(n>=0 && n<200)){ if(mciSendString(_T("play E+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play E+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=330 && m<440)&&(n>=0 && n<200)){ if(mciSendString(_T("play F+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play F+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=440 && m<550)&&(n>=0 && n<200)){ if(mciSendString(_T("play G+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play G+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=550 && m<660)&&(n>=0 && n<200)){ if(mciSendString(_T("play A+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play A+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=660 && m<770)&&(n>=0 && n<200)){ if(mciSendString(_T("play B+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play B+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if(mciSendString(_T("play C.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play C.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=110 && m<220)&&(n>=200 && n<400)){ if(mciSendString(_T("play D.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play D.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; 以下省略 . . . }else{ break; } } } free(temp); fclose(fp); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wParam, lParam)); } return 0; }

  • 動画再生のマクロ.について教えて下さい

    エクセルVBA2003対応 の マクロについて教えて下さい 現在 エクセルシートのセルC20とセルC10に、下記の場所に保存された動画を再生するようにハイパーリンクが設定してあります C20 → C:\Documents and Settings\ビデオ\○×.mpg C10 → C:\Documents and Settings\ビデオ\○×.vob 上記の環境の中で、下記のマクロsample1は、mpg動画の為、mplay32.exeで再生が出来ます。 しかし、マクロsample2は、VOB動画の為、VOB動画を再生するvlc.exeに書き変えてありますが,「ファイルが見つかりません」のエラーがでて、再生が出来ません。 ちなみに、vlc.exeの保存場所は、C:\Program Files\Vlc\vlc.exeに存在しています。 VOB動画を再生するためには、マクロsample2をどのように改造すればよいのか どなたか教えてください よろしくお願いいたします Sub sample1() Dim sAddr As String On Error Resume Next sAddr = Range("C20").Hyperlinks(1).Address On Error GoTo Err_ sAddr = Chr(34) & sAddr & Chr(34) Call Shell("mplay32.exe /play /close " & sAddr, vbNormalFocus) Bye_: Exit Sub Err_: MsgBox Err.Description, vbCritical Resume Bye_ End Sub Sub sample2() Dim sAddr As String On Error Resume Next sAddr = Range("C10").Hyperlinks(1).Address On Error GoTo Err_ sAddr = Chr(34) & sAddr & Chr(34) Call Shell("vlc.exe /play /close " & sAddr, vbNormalFocus) Bye_: Exit Sub Err_: MsgBox Err.Description, vbCritical Resume Bye_ End Sub

専門家に質問してみよう