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