บทที่ 5 ตอน 4 โปรแกรมสร้างเสียงเครื่องเล่นคีย์บอร์ด

ตัวอย่างที่ 1 โปรแกรมสร้างเสียงเครื่องเล่นคีย์บอร์ด

ในตัวอย่างต่อไปนี้เป็นการสร้างเสียงจากเครื่องดนตรีจำนวน 128 เสียงจาก เว็บเทเบิลภายในซาวด์การ์ดในรูปแบบของ midi (midi karaoke) ซึ่งโปรแกรมนี้จะเป็นตัวอย่างการสร้างเครื่องเล่นคีย์บอร์ดอย่างง่าย ซึ่งนักศึกษาสามารถนำไปพัฒนาต่อยอดได้หลากหลายรูปแบบ

0
Acoustic Grand Piano
32
Acoustic Bass
64
Soprano Sax
96
Ice Rain
1
Bright Acoustic Piano
33
Fingered Bass
65
Alto Sax
97
Sound Track
2
Electric Grand Piano
34
Picked Bass
66
Tenor Sax
98
Crystal
3
Honky Tonk Piano
35
Fretless Bass
67
Baritone Sax
99
Atmosphere
4
Electric Piano 1
36
Slap Bass 1
68
Oboe
100
Brightness
5
Electric Piano 2
37
Slap Bass 2
69
English Horn
101
Goblin
6
Harpsichord
38
Synth Bass 1
70
Basson
102
Echo Drops
7
Clavinet
39
Synth Bass 2
71
Clarinet
103
Star Theme
8
Celesta
40
Violin
72
Piccolo
104
Sitar
9
Glockenspiel
41
Viola
73
Flute
105
Banjo
10
Music Box
42
Cello
74
Recorder
106
Shamisen
11
Vibraphone
43
Contrabass
75
Pan Flute
107
Koto
12
Marimba
44
Tremolo Strings
76
Bottle Blow
108
Kalimba
13
Xylophone
45
Pizzicato Strings
77
Shakuhachi
109
Bag Pipe
14
Tubular Bell
46
Orchestral Strings
78
Whistle
110
Fiddle
15
Dulcimer
47
Timpani
79
Ocarina
111
Shanai
16
Drawbar Organ
48
String Ensemble 1
80
Square Wave
112
Tinkle Bell
17
Percussive Organ
49
String Ensemble 2
81
Sawtooth Wave
113
Agogo
18
Rock Organ
50
Syn Str. 1
82
Syn.Calliope
114
Steel Drums
19
Church Organ
51
Syn Str. 2
83
Chiffer Lead
115
Woodblock
20
Reed Organ
52
Choir Aahs
84
Charang
116
Taiko
21
Accordion
53
Voice Oohs
85
Solo Vox
117
Melo Tom 1
22
Harmonica
54
SynVox
86
5th Saw Wave
118
Synth Drum
23
Tango Accordion
55
Orchestra Hit
87
Bass& Lead
119
Reverse Cym.
24
Nylon String Guitar
56
Trumpet
88
Fantasia
120
Gt.FretNoise
25
Steel String Guitar
57
Trombone
89
Warm Pad
121
Breath Noise
26
Electric Jazz Guitar
58
Tuba
90
PolySynth
122
Seashore
27
Electric Clean Guitar
59
Muted Trumpet
91
Space Voice
123
Bird
28
Electric Muted Guitar
60
French Horn
92
Bowed Glass
124
Telephone 1
29
Overdrive Guitar
61
Brass Section
93
Metal Pad
125
Helicopter
30
Distortion Guitar
62
Synth Brass 1
94
Halo Pad
126
Applause
31
Guitar Harmonics
63
Synth Brass 2
95
Sweep Pad
127
Gun Shot

(1) ออกแบบหน้าจออย่าง่ายดังภาพ 


(2)  สร้างคลาส clsMidi.vb เพื่อใช้ติดต่อกับซาวด์การ์ดในการสร้างเสียงเครื่องดนตรี ซึ่งคลาสนี้มีชุดคำสั่งมาก ดังนั้นอาจจะพิมพ์คำสั่งผิดพลาดดังนั้นให้ดาว์นโหลด คลาส clsMidi.vb จะอยู่ในตำแหน่ง http://www.teacherroom.net/oop/clsmidi.vb ซึ่งจะมีโค้ดคำสั่งดังนี้

|1|  Public Class clsMidi
|2|      Private Const MAXPNAMELEN As Short = 32 '  max product name length (including NULL)
|3|      Private Const MAXERRORLENGTH As Short = 128 '  max error text length (including NULL)
|4|      Private Declare Function midiOutShortMsg Lib "winmm.dll" (ByVal hMidiOut As Integer, ByVal dwMsg As Integer) As Integer
|5|      Private Declare Function midiOutGetErrorText Lib "winmm.dll" Alias "midiOutGetErrorTextA" (ByVal err_Renamed As Integer, ByVal lpText As String, ByVal uSize As Integer) As Integer
|6|      Private Declare Function midiOutClose Lib "winmm.dll" (ByVal hMidiOut As Integer) As Integer
|7|      Private Declare Function midiOutOpen Lib "winmm.dll" (ByRef lphMidiOut As Integer, ByVal uDeviceID As Integer, ByVal dwCallback As Integer, ByVal dwInstance As Integer, ByVal dwFlags As Integer) As Integer
|8|      Private m_hmidiout As Integer
|9|      '-----------------------------------------------
|10|     Protected Sub note_on(ByRef ch As Short, ByVal kk As Short, ByRef v As Short)
|11|         Call midi_outshort(&H90 + ch, kk, v)
|12|     End Sub
|13|     '-----------------------------------------------
|14|     Protected Sub note_off(ByRef ch As Short, ByVal kk As Short)
|15|         Call midi_outshort(&H90 + ch, kk, 0)
|16|     End Sub
|17|     '-----------------------------------------------
|18|     Private Function packdword(ByRef i1 As Short, ByRef i2 As Short, ByRef i3 As Short, ByRef i4 As Short) As Integer
|19|         packdword = i2 * &H10000 + i3 * &H100 + i4
|20|     End Function
|21|     '-----------------------------------------------
|22|     Private Sub midi_outerr(ByVal midi_error As Short)
|23|         Dim s As String
|24|         Dim X As Short
|25|
|26|         s = Space(MAXERRORLENGTH)
|27|         X = midiOutGetErrorText(midi_error, s, MAXERRORLENGTH)
|28|         MsgBox(s)
|29|     End Sub
|30|     '-----------------------------------------------
|31|     Protected Sub midi_out_close()
|32|         Dim midi_error As Short
|33|
|34|         If m_hmidiout <> 0 Then
|35|             midi_error = midiOutClose(m_hmidiout)
|36|             If Not midi_error = 0 Then
|37|                 Call midi_outerr(midi_error)
|38|             End If
|39|             m_hmidiout = 0
|40|         End If
|41|     End Sub
|42|     '-----------------------------------------------
|43|     Protected Function midi_out_open(ByVal dev_id As Short) As Short
|44|         Dim midi_error As Short
|45|
|46|         midi_out_close() ' just in case (And it dont hurt)
|47|         midi_error = midiOutOpen(m_hmidiout, dev_id, 0, 0, 0)
|48|         If Not midi_error = 0 Then
|49|             Call midi_outerr(midi_error)
|50|         End If
|51|         midi_out_open = (m_hmidiout <> 0)
|52|     End Function
|53|     '-----------------------------------------------
|54|     Protected Sub midi_outshort(ByRef b1 As Short, ByRef b2 As Short, ByRef b3 As Short)
|55|         Dim midi_error As Short
|56|
|57|         midi_error = midiOutShortMsg(m_hmidiout, packdword(0, b3, b2, b1))
|58|         If Not midi_error = 0 Then
|59|             Call midi_outerr(midi_error)
|60|         End If
|61|     End Sub
|62|     '-----------------------------------------------
|63|     Protected Sub control_change(ByRef ch As Short, ByRef ccnr As Short, ByVal v As Short)
|64|         Call midi_outshort(&HB0 + ch, ccnr, v)
|65|     End Sub
|66| End Class

จากโค้ดจะสังเกตได้ว่าจะมีเมธอดบางตัวที่มีคีย์เวิร์ดคำว่า Protected นำหน้าอยู่นั้นแสดงถึงการปกป้องข้อมูลในระดับของการสืบทอดคลาส ซึ่งเมื่อนำไปสร้างออบเจ็กต์เมธอดเหล่านี้จะไม่สามารถมองเห็นหรือไม่สามารถเข้าถึงได้

(3)  สร้างคลาส clsPiano.vb เพื่อสร้างเมธอดสำหรับการติดต่อกับคลาสฟอร์ม

|1|  Public Class clsPiano
|2|      Inherits clsMidi
|3|      '--------------------------------
|4|      Sub New()
|5|          midi_out_close()
|6|          midi_out_open(0)
|7|      End Sub
|8|      '--------------------------------
|9|      Public Sub StartNote(ByVal prmIndex As Integer)
|10|         note_on(0, (53 + prmIndex), 127)
|11|     End Sub
|12|     '--------------------------------
|13|     Public Sub StopNote(ByVal prmIndex As Integer)
|14|         note_off(0, (53 + prmIndex))
|15|     End Sub
|16|     '--------------------------------
|17|     Public Sub program_change(ByRef ch As Short, ByRef cc0nr As Short, ByVal pnr As Short)
|18|         Call control_change(ch, 0, cc0nr)
|19|         Call midi_outshort(&HC0 + ch, pnr, 0)
|20|     End Sub
|21| End Class

บรรทัดที่ 2 คือการสืบทอดคลาส clsMidi ซึ่งสามารถดาวน์โหลดจากลิงค์ที่กล่าวมาแล้ว
บรรทัดที่ 4 ถึง 7  คือการทำคอนสตรัคเตอร์คลาส เพื่อให้เรียกใช้เมธอดเกี่ยวกับการติดต่อกับซาวด์การ์ด
บรรทัดที่ 9 ถึง 11    คือเมธอดสำหรับการเริ่มเสียงดนตรี พารามิเตอร์ที่รับเข้ามาจะเป็นค่าของโน๊ตเพลง
บรรทัดที่ 13 ถึง 15  คือเมธอดสำหรับการหยุดเสียงดนตรี พารามิเตอร์เดียวกันกับเมธอด StartNote()
บรรทัดที่ 17 ถึง 21  คือเมธอดสำหรับการเลือกเสียงของเครื่องดนตรี ซึ่งจะมีพารามิเตอร์จำนวน 3 ค่า
                            คือ 0
, 0, ดัชนีของเครื่องดนตรี (0-127)

(4)  เขียนโค้ดในฟอร์มจะขอยกตัวอย่างเพียงบางปุ่มเท่านั้น บันไดเสียงจะใช้เป็นเลขคี่ ส่วนเลขคู่นั้นจะเป็นเสียงไมเนอร์ หรือเสียงกลาง ในโปรแกรมนี้จะมีเหตุการณ์ของปุ่มอยู่ 2 เหตุการณ์คือ
- MouseDown คือเหตุการณ์ที่สั่งให้มีเสียง
- MouseUp     คือเหตุการณ์ที่หยุดเสียง

จากนั้นเขียนคำสั่งดังนี้โดยที่ (....) คือ
 (ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)

|1|  Public Class Form1
|2|      Dim obj As New clsPiano
|3|      '--------------------------------------------
|4|      Private Sub Form1_Load(....) Handles MyBase.Load
|5|          TextBox1.Text = 0
|6|      End Sub
|7|      '--------------------------------------------
|8|      Private Sub TextBox1_TextChanged(....) Handles TextBox1.TextChanged
|9|          obj.program_change(0, 0, Val(TextBox1.Text))
|10|     End Sub
|11|     '--------------------------------------------
|12|     Private Sub Button1_MouseDown(....) Handles Button1.MouseDown
|13|         obj.StartNote(1)
|14|     End Sub
|15|     '--------------------------------------------
|16|     Private Sub Button1_MouseUp(....) Handles Button1.MouseUp
|17|         obj.StopNote(1)
|18|     End Sub
|19|     '--------------------------------------------
|20|     Private Sub Button2_MouseDown(....) Handles Button2.MouseDown
|21|         obj.StartNote(3)
|22|     End Sub
|23|     '--------------------------------------------
|24|     Private Sub Button2_MouseUp(....) Handles Button2.MouseUp
|25|         obj.StopNote(3)
|26|     End Sub
|27| End Class

(4)  เมื่อรันโปรแกรมและทดสอบคลิกที่ปุ่ม ด และ ร ก็จะมีเสียงเปียโนออกมา จากนั้นทดสอบใส่ค่า 92 จะเป็นเสียง Bowed Glass (เครื่องเป่าแก้ว)
(5)  ให้นักศึกษาทำให้ครบทุกปุ่มแล้วทดลองฟังเสียง ซึ่งโปรแกรมตัวเต็มนั้นจะออกแบบหน้าจอดังนี้


ในโปรแกรมตัวอย่างนี้ได้ตัดเอาเพียงคุณสมบัติ และความสามารถบางส่วนของโปรแกรมเปียโนมาเท่านั้น 
ดังนั้นโปรดสังเกตว่าส่วนใดของโปรแกรมที่ขาดหายไปและโปรแกรมนี้ควรมีความสามารถอะไรเพิ่มเติมบ้าง


ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

บทที่ 11 ตอน 3 การออกแบบรายงานด้วย Crystal Report

บทที่ 6 กระบวนการพอลิมอร์ฟิซึม (Polymorphism)

บทที่ 11 ตอน 3 การออกแบบรายงานด้วย Crystal Report Ex2