Imports System.IO Public Class Form1 Dim WaveByte() As Byte 'Waveのバイト配列 Dim SampleRate As Int32 'サンプルレート Dim cdtix As Integer '自動演奏データ位置 Dim ButtonArray() As Button 'キーボタンの配列 Dim PlayData(,) As String = {{"C2", "500"}, {"C2", "500"}, {"G2", "500"}, {"G2", "500"}, {"A3", "500"}, {"A3", "500"}, {"G2", "1000"}, _ {"F2", "500"}, {"F2", "500"}, {"E2", "500"}, {"E2", "500"}, {"D2", "500"}, {"D2", "500"}, {"C2", "1000"}} '曲データ Dim HZ() As Double = {261.63, 293.66, 329.63, 349.23, 392, 440, 493.88, 523.25} 'C3-C4周波数 Dim CdAr() As String = {"C2", "D2", "E2", "F2", "G2", "A3", "B3", "C3"} 'コード文字と周波数位置を合わせるための配列 '初期化 Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load ButtonArray = {Button1, Button2, Button3, Button4, Button5, Button6, Button7, Button8} For i = 0 To ButtonArray.Length - 1 AddHandler ButtonArray(i).Click, _ AddressOf Me.KeyButtons_Click Next i End Sub 'ファイル読み込み Private Sub FileButton_Click(sender As System.Object, e As System.EventArgs) Handles FileButton.Click OpenFileDialog1.Filter = "wave|*.wav" If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then Dim waveFile As String = OpenFileDialog1.FileName TextBox1.Text = waveFile ReadWaveByte(waveFile) End If End Sub 'WAVEをバイト配列に保存 Private Sub ReadWaveByte(ByVal filename As String) Dim fs As New System.IO.FileStream(filename, _ System.IO.FileMode.Open, _ System.IO.FileAccess.Read) 'ファイルを読み込むバイト型配列を作成する ReDim WaveByte(fs.Length - 1) 'ファイルの内容をすべて読み込む fs.Read(WaveByte, 0, WaveByte.Length) '閉じる fs.Close() Dim wrate(3) As Byte 'サンプルレートを保存する For i = 24 To 27 wrate(i - 24) = WaveByte(i) Next SampleRate = BitConverter.ToInt32(wrate, 0) End Sub 'KeyButtonのクリックイベントハンドラ Private Sub KeyButtons_Click(ByVal sender As Object, _ ByVal e As EventArgs) Dim s As String = CType(sender, System.Windows.Forms.Button).Name s = s.Replace("Button", "") 'ボタン名から数字部分のみ取り出す Try Dim i As Integer = CInt(s) - 1 MyPlaySound(i) Catch ex As Exception End Try End Sub Private Sub MyPlaySound(ByVal KeyNo As Integer) Dim r As Double = HZ(KeyNo) / 440 'ここでは音源はラの音として処理している。実際には変数を使用 'サンプルレートを書き込む Dim br As Int32 br = CInt(SampleRate * r) Dim bt() As Byte = BitConverter.GetBytes(br) For i = 24 To 27 WaveByte(i) = bt(i - 24) Next 'Waveファイルを作って鳴らす Dim WMemoryStream As New MemoryStream WMemoryStream.Write(WaveByte, 0, WaveByte.Length) WMemoryStream.Seek(0, SeekOrigin.Begin) Dim player1 As System.Media.SoundPlayer player1 = New System.Media.SoundPlayer(WMemoryStream) 'player1.Stop() player1.Play() End Sub 'PLAY Private Sub PlayButton_Click(sender As System.Object, e As System.EventArgs) Handles PlayButton.Click Timer1.Interval = 1 cdtix = 0 Timer1.Start() End Sub '自動演奏 タイマー使用 Private Sub Timer1_Tick(sender As Object, e As System.EventArgs) Handles Timer1.Tick If cdtix < 0 Or cdtix >= PlayData.Length / 2 Then 'データが無いので停止 Timer1.Stop() Exit Sub End If Dim Code As String = PlayData(cdtix, 0) 'コードを取り出す Dim ix = Array.IndexOf(CdAr, Code) 'コードからキー位置を調べる If ix >= 0 And ix < ButtonArray.Length Then Dim Len As Integer = CInt(PlayData(cdtix, 1)) '音を鳴らす時間を得る ButtonArray(ix).PerformClick() '音を鳴らす Timer1.Stop() Timer1.Interval = Len '音を鳴らす時間が過ぎたら次のコールが来るようにする Timer1.Start() End If cdtix = cdtix + 1 End Sub 'PLAY2 自動演奏ループ Private Sub Play2Button_Click(sender As System.Object, e As System.EventArgs) Handles Play2Button.Click Dim StWt As New System.Diagnostics.Stopwatch() cdtix = 0 Dim CT As Int32 = -1 Dim LPCT As Integer = 0 StWt.Reset() StWt.Start() While True If CT = -1 Then CT = StWt.ElapsedMilliseconds LPCT = LPCT + 1 If cdtix < 0 Or cdtix >= PlayData.Length / 2 Then 'データが無いので停止 StWt.Stop() Exit While Else If StWt.ElapsedMilliseconds > CT Then Try Dim Len As Integer = CInt(PlayData(cdtix, 1)) '音を鳴らす時間を得る CT = CT + Len Dim Code As String = PlayData(cdtix, 0) 'コードを取り出す Dim ix = Array.IndexOf(CdAr, Code) 'コードからキー位置を調べる If ix >= 0 And ix < ButtonArray.Length Then MyPlaySound(ix) End If cdtix = cdtix + 1 Catch ex As Exception End Try End If End If End While End Sub End Class |