]> code.delx.au - virtualtones/blob - pianoinstrument.cpp
Updated the README a litte..
[virtualtones] / pianoinstrument.cpp
1 // pianoinstrument.cpp - A piano simulator
2 // Written by James Bunton <james@delx.cjb.net>
3 // Licensed under the GPL, see COPYING.txt for more details
4
5
6 #include "pianoinstrument.h"
7
8
9
10
11 PianoInstrument::PianoInstrument(QWidget *parent)
12 : Instrument(parent)
13 {
14 // Set us up to look pretty
15 setPaletteBackgroundPixmap(QPixmap("piano.png"));
16 setFixedSize(184, 220);
17 parentWidget()->setFixedSize(184, 220);
18
19 for(int i = 0; i < 26; i++) {
20 oldNotes[i] = false;
21 notes[i] = false;
22 }
23
24 noteStart = 48;
25
26 emitSounds();
27 }
28
29 PianoInstrument::~PianoInstrument()
30 {
31
32 }
33
34 QString PianoInstrument::generateHelp()
35 {
36 QString help;
37 help +=
38
39 "<html>"
40
41 "Playing the keyboard:"
42 "<ul>"
43 "<li>You can change the octave using the &quot;Octave&quot; box above. Middle C is the third octave</li>"
44 "<li>The keys - qwertyui are the top row white keys</li>"
45 "<li>The keys - 23 567 9 are the top row black keys</li>"
46 "<li>The keys - zxcvbnm, are the bottom row white keys</li>"
47 "<li>The keys - sd ghj l are the bottom row black keys</li>"
48 "</ul>"
49
50 "</html>"
51 ;
52 return help;
53 }
54
55
56 void PianoInstrument::paintEvent(QPaintEvent *)
57 {
58 QPainter paint(this);
59 paint.setPen(Qt::red);
60
61 const int topBlackY = 38;
62 const int topWhiteY = 70;
63 const int botBlackY = 38 + 110;
64 const int botWhiteY = 70 + 110;
65 const int w = 10;
66 const int h = 10;
67
68 if(notes[0] == true) {
69 paint.drawEllipse(6, topWhiteY, w, h);
70 }
71 if(notes[1] == true) {
72 paint.drawEllipse(15, topBlackY, w, h);
73 }
74 if(notes[2] == true) {
75 paint.drawEllipse(29, topWhiteY, w, h);
76 }
77 if(notes[3] == true) {
78 paint.drawEllipse(45, topBlackY, w, h);
79 }
80 if(notes[4] == true) {
81 paint.drawEllipse(52, topWhiteY, w, h);
82 }
83 if(notes[5] == true) {
84 paint.drawEllipse(75, topWhiteY, w, h);
85 }
86 if(notes[6] == true) {
87 paint.drawEllipse(85, topBlackY, w, h);
88 }
89 if(notes[7] == true) {
90 paint.drawEllipse(97, topWhiteY, w, h);
91 }
92 if(notes[8] == true) {
93 paint.drawEllipse(113, topBlackY, w, h);
94 }
95 if(notes[9] == true) {
96 paint.drawEllipse(120, topWhiteY, w, h);
97 }
98 if(notes[10] == true) {
99 paint.drawEllipse(136, topBlackY, w, h);
100 }
101 if(notes[11] == true) {
102 paint.drawEllipse(143, topWhiteY, w, h);
103 }
104 if(notes[12] == true) {
105 paint.drawEllipse(166, topWhiteY, w, h);
106 paint.drawEllipse(6, botWhiteY, w, h);
107 }
108 if(notes[13] == true) {
109 paint.drawEllipse(176, topBlackY, w, h);
110 paint.drawEllipse(15, botBlackY, w, h);
111 }
112 if(notes[14] == true) {
113 paint.drawEllipse(29, botWhiteY, w, h);
114 }
115 if(notes[15] == true) {
116 paint.drawEllipse(45, botBlackY, w, h);
117 }
118 if(notes[16] == true) {
119 paint.drawEllipse(52, botWhiteY, w, h);
120 }
121 if(notes[17] == true) {
122 paint.drawEllipse(75, botWhiteY, w, h);
123 }
124 if(notes[18] == true) {
125 paint.drawEllipse(85, botBlackY, w, h);
126 }
127 if(notes[19] == true) {
128 paint.drawEllipse(97, botWhiteY, w, h);
129 }
130 if(notes[20] == true) {
131 paint.drawEllipse(113, botBlackY, w, h);
132 }
133 if(notes[21] == true) {
134 paint.drawEllipse(120, botWhiteY, w, h);
135 }
136 if(notes[22] == true) {
137 paint.drawEllipse(136, botBlackY, w, h);
138 }
139 if(notes[23] == true) {
140 paint.drawEllipse(143, botWhiteY, w, h);
141 }
142 if(notes[24] == true) {
143 paint.drawEllipse(166, botWhiteY, w, h);
144 }
145 if(notes[25] == true) {
146 paint.drawEllipse(176, botBlackY, w, h);
147 }
148
149 }
150
151
152 void PianoInstrument::keyPressEvent(QKeyEvent *e)
153 {
154 if(e->isAutoRepeat() == true) {
155 e->ignore();
156 return;
157 }
158
159 // Make a copy of the old notes so we know what's changed
160 copyArray(notes, oldNotes);
161
162 switch(e->key()) {
163
164 /* First row of keys */
165 case Key_Q:
166 notes[0] = true;
167 break;
168 case Key_2:
169 notes[1] = true;
170 break;
171 case Key_W:
172 notes[2] = true;
173 break;
174 case Key_3:
175 notes[3] = true;
176 break;
177 case Key_E:
178 notes[4] = true;
179 break;
180 case Key_R:
181 notes[5] = true;
182 break;
183 case Key_5:
184 notes[6] = true;
185 break;
186 case Key_T:
187 notes[7] = true;
188 break;
189 case Key_6:
190 notes[8] = true;
191 break;
192 case Key_Y:
193 notes[9] = true;
194 break;
195 case Key_7:
196 notes[10] = true;
197 break;
198 case Key_U:
199 notes[11] = true;
200 break;
201 case Key_I:
202 notes[12] = true;
203 break;
204 case Key_9:
205 notes[13] = true;
206 break;
207
208 /* Second row of keys */
209 case Key_Z:
210 notes[12] = true;
211 break;
212 case Key_S:
213 notes[13] = true;
214 break;
215 case Key_X:
216 notes[14] = true;
217 break;
218 case Key_D:
219 notes[15] = true;
220 break;
221 case Key_C:
222 notes[16] = true;
223 break;
224 case Key_V:
225 notes[17] = true;
226 break;
227 case Key_G:
228 notes[18] = true;
229 break;
230 case Key_B:
231 notes[19] = true;
232 break;
233 case Key_H:
234 notes[20] = true;
235 break;
236 case Key_N:
237 notes[21] = true;
238 break;
239 case Key_J:
240 notes[22] = true;
241 break;
242 case Key_M:
243 notes[23] = true;
244 break;
245 case Key_Comma:
246 notes[24] = true;
247 break;
248 case Key_L:
249 notes[25] = true;
250 break;
251 default:
252 e->ignore();
253 return;
254 }
255 e->accept();
256 emitSounds();
257 }
258
259 void PianoInstrument::keyReleaseEvent(QKeyEvent *e)
260 {
261 if(e->isAutoRepeat() == true) {
262 e->ignore();
263 return;
264 }
265
266 // Make a copy of the old notes so we know what's changed
267 copyArray(notes, oldNotes);
268
269 switch(e->key()) {
270
271 /* First row of keys */
272 case Key_Q:
273 notes[0] = false;
274 break;
275 case Key_2:
276 notes[1] = false;
277 break;
278 case Key_W:
279 notes[2] = false;
280 break;
281 case Key_3:
282 notes[3] = false;
283 break;
284 case Key_E:
285 notes[4] = false;
286 break;
287 case Key_R:
288 notes[5] = false;
289 break;
290 case Key_5:
291 notes[6] = false;
292 break;
293 case Key_T:
294 notes[7] = false;
295 break;
296 case Key_6:
297 notes[8] = false;
298 break;
299 case Key_Y:
300 notes[9] = false;
301 break;
302 case Key_7:
303 notes[10] = false;
304 break;
305 case Key_U:
306 notes[11] = false;
307 break;
308 case Key_I:
309 notes[12] = false;
310 break;
311 case Key_9:
312 notes[13] = false;
313 break;
314
315 /* Second row of keys */
316 case Key_Z:
317 notes[12] = false;
318 break;
319 case Key_S:
320 notes[13] = false;
321 break;
322 case Key_X:
323 notes[14] = false;
324 break;
325 case Key_D:
326 notes[15] = false;
327 break;
328 case Key_C:
329 notes[16] = false;
330 break;
331 case Key_V:
332 notes[17] = false;
333 break;
334 case Key_G:
335 notes[18] = false;
336 break;
337 case Key_B:
338 notes[19] = false;
339 break;
340 case Key_H:
341 notes[20] = false;
342 break;
343 case Key_N:
344 notes[21] = false;
345 break;
346 case Key_J:
347 notes[22] = false;
348 break;
349 case Key_M:
350 notes[23] = false;
351 break;
352 case Key_Comma:
353 notes[24] = false;
354 break;
355 case Key_L:
356 notes[25] = false;
357 break;
358 default:
359 e->ignore();
360 return;
361 }
362 e->accept();
363 emitSounds();
364 }
365
366 void PianoInstrument::copyArray(bool source[26], bool dest[26])
367 {
368 for(int i = 0; i < 26; i++) {
369 dest[i] = source[i];
370 }
371 }
372
373 void PianoInstrument::emitSounds()
374 {
375 for(int i = 0; i < 26; i++) {
376 if(notes[i] == oldNotes[i]) continue;
377
378 if(notes[i] == false)
379 emit stopNote(i + noteStart);
380 else {
381 emit playNote(i + noteStart, 120, 0);
382 }
383 }
384
385 repaint();
386 }
387