Excelでドラム演奏(mciSendString関数でmp3再生)

好きなんです、ドラム(1回しか叩いたこと無いけど)。

叩きたくなりますよね、ドラム(ドラムマニアは何度か)。

無理からにExcelで作ってみました、ドラム(不安定だけど)。

どんなもの

事前にキーボードのキーと再生する音の組み合わせを決めておきます。

指定していたキーを押すと組み合わせていた音が再生されます。

その再生する音をドラムのシンバルやスネアの音にしておくと

さながらドラムのようになる、というものです。

用意したもの

・ドラムの音

こちらのサイトでアカウント登録して取得しました。

www.samplephonics.com

(海外サイトへのアカウント登録する危険性・ダウンロードの危険性に関してはご自分でご判断を)

・設定画面 f:id:ExcelLover:20180811232747j:plain

A列:キーボードのキー(コードの中では使用しません。見た目のわかり易さのみ)

B列:A列記載のキーのキーコード。この数字でどのキーを押下したか判断します。

C列:キーを押下した際に鳴らす音声ファイルのフルパスを指定。

コード

Option Explicit
'①
Public Declare Function mciSendString Lib "Winmm.dll" Alias "mciSendStringA" (ByVal lpMciComm As String, ByVal lpMciRetString As String, ByVal lpRetLength As Long, ByVal CallBackhWnd As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
Dim myDic As Dictionary
'-------------------------------------------------------------------------------
Sub Excel_Drum_Start()
     Dim myPath As String
     Dim DrumSoundFiles As Range
     Dim DrumSoundFile As Range
     Dim i As Long
     
     Set myDic = New Dictionary
     Set DrumSoundFiles = Range("C2:C8")
     For Each DrumSoundFile In DrumSoundFiles
          myPath = """" & DrumSoundFile.Value & """"
'②                        
          mciSendString "Open " & myPath & " alias Drum" & i, vbNullString, 0, 0
          myDic.Add DrumSoundFile.Offset(, -1).Value, "Drum" & i
          i = i + 1
     Next                 
     Drum_Play
'⑦                    
     mciSendString "Close all", vbNullString, 0, 0
End Sub
'-------------------------------------------------------------------------------
Sub Drum_Play()
     Dim PlayFlag As Boolean
     Dim myKey As Variant
     PlayFlag = True
'③     
     Do While PlayFlag = True
          For Each myKey In myDic
'④                        
               If GetAsyncKeyState(myKey) And &H8000 Then
                    mciSendString "Play " & myDic.Item(myKey) & " from 0", vbNullString, 0, 0
'⑤                            
               ElseIf GetAsyncKeyState(27) Then
                    PlayFlag = False
               End If
'⑥                        
               Sleep 10
          Next
          DoEvents
     Loop
End Sub

ユーザーフォームを1つ用意して、その上にコマンドボタンを1つ設定しました。 コマンドボタンを押下すると上記コードの「Excel_Drum_Start」が実行されます。

API関数を3種類使用しています。

・mciSendString…音声ファイルを再生するための関数。
・Sleep…ループ処理の途中で処理を指定時間休止させることが出来ます。
・GetAsyncKeyState…押下されたキーを取得する関数

②mciSendString関数は音声ファイルを開く・再生する・閉じるの3段階構成です。 まずは音声ファイルを開く

mciSendString "Open ファイルのフルパス Alias 〇〇〇 ,vbNullString,0,0"

Alias 〇〇〇…今後、ファイルの再生・閉じるを行う際にはこの〇〇〇で処理する音声ファイルを指定する。
毎回フルパスを指定しなくて良くなる。変数に代入している感じでしょうか。 〇〇〇は任意で設定してください。

キーコードと指定した〇〇〇をDictionaryオブジェクトに代入。 キーコードをキーにして組み合わされた〇〇〇を抽出します。

③ここから実際の音声再生です。 「ESC」ボタンを押下するまではずーっとループしっぱなしです。

④押下されたキーの判定を行っています。
Dictionaryオブジェクトに格納されたキーコードと押下されたキーのキーコードが一致したときに、 Dictionaryオブジェクト内で関連付けられた〇〇〇の音声ファイルを再生します。

mciSendString "Play 〇〇〇 from 0 ,vbNullString,0,0"

第1引数にPlay + ファイルのAlias(〇〇〇)。from 0は音声ファイルの最初から再生の意味。 第2ー第4までの引数はこのままで(よくわからん)

⑤キーコード27はEscボタンを意味します。Escボタンを押下したときにフラグを立ててループ処理を抜けます。

⑥Escボタンを押すまでは無限ループですので、Sleepを間に挟むことでCPUが動きっぱなしになることを防ぎます。

⑦mciSendString関数のお作法、ファイルを閉じます。

mciSendString "Close 〇〇〇 from 0 ,vbNullString,0,0"

上記のように1つずつAliasを指定して閉じる方法もありますが、今回のコードのように「Close all」と記載することで開いている音声ファイルを全て閉じることができるようです。

まとめ

なかなか面白いものが出来ました。キーを押し続けるとデスメタルバンドのドラマーさながらの高速連打を堪能できます。
CRYPTOPSY - Worship Your Demons (OFFICIAL VIDEO) - YouTube
デスメタルの演奏風景が流れますから、イヤな人は要注意

今回使用したmciSendString関数は現在チマチマと作り続けている、Excel Playerでも使用する予定ですのでその予行演習も兼ねていました。

おまけ

キーを3回連続で押すと自動的にデスメタルドラマーと化す(連打が止まらない)ボタンがあったり、再生できないmp3ファイルがあったりと課題も見つかりました。

解決できれば良いですけど、最低限自分がやりたいことの実現が最優先ですのでホドホドに調べていきます。

参考資料

今回こちらの動画を見て作ってみようと思いたちました。
www.youtube.com
shadowslasheizan.blog114.fc2.com

Excel VBA アクションゲーム作成入門 Excel 2007/2003/2002 対応

Excel VBA アクションゲーム作成入門 Excel 2007/2003/2002 対応