บทที่ 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)
คือ 0 , 0, ดัชนีของเครื่องดนตรี (0-127)
(4) เขียนโค้ดในฟอร์มจะขอยกตัวอย่างเพียงบางปุ่มเท่านั้น
บันไดเสียงจะใช้เป็นเลขคี่ ส่วนเลขคู่นั้นจะเป็นเสียงไมเนอร์ หรือเสียงกลาง
ในโปรแกรมนี้จะมีเหตุการณ์ของปุ่มอยู่ 2 เหตุการณ์คือ
- MouseDown คือเหตุการณ์ที่สั่งให้มีเสียง
- MouseUp คือเหตุการณ์ที่หยุดเสียง
จากนั้นเขียนคำสั่งดังนี้โดยที่ (....) คือ
(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
(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) ให้นักศึกษาทำให้ครบทุกปุ่มแล้วทดลองฟังเสียง
ซึ่งโปรแกรมตัวเต็มนั้นจะออกแบบหน้าจอดังนี้
ในโปรแกรมตัวอย่างนี้ได้ตัดเอาเพียงคุณสมบัติ และความสามารถบางส่วนของโปรแกรมเปียโนมาเท่านั้น
ดังนั้นโปรดสังเกตว่าส่วนใดของโปรแกรมที่ขาดหายไปและโปรแกรมนี้ควรมีความสามารถอะไรเพิ่มเติมบ้าง
ดังนั้นโปรดสังเกตว่าส่วนใดของโปรแกรมที่ขาดหายไปและโปรแกรมนี้ควรมีความสามารถอะไรเพิ่มเติมบ้าง
ความคิดเห็น
แสดงความคิดเห็น