]>
code.delx.au - virtualtones/blob - stringinstrument.cpp
8d369a1b1d9f106a3fe0083d81ef635d642b154d
1 // stringinstrument.cpp - A stringed instrument simulator
2 // Written by James Bunton <james@delx.cjb.net>
3 // Licensed under the GPL, see COPYING.txt for more details
6 #include "stringinstrument.h"
8 // Images from http://www.asinari.it/bassoeng.htm
10 ViolinInstrument::ViolinInstrument(QWidget
*parent
)
11 : StringInstrument(parent
)
15 // Set us up to look pretty
16 setPaletteBackgroundPixmap(QPixmap("violin.png"));
17 setFixedSize(637, 384);
18 parentWidget()->setFixedSize(637,384);
23 void ViolinInstrument::setNotes(int array
[4])
25 array
[0] = 28; // 'E' string
26 array
[1] = 21; // 'A' string
27 array
[2] = 14; // 'D' string
28 array
[3] = 7; // 'G' string
33 ViolaInstrument::ViolaInstrument(QWidget
*parent
)
34 : StringInstrument(parent
)
38 // Set us up to look pretty
39 setPaletteBackgroundPixmap(QPixmap("viola.png"));
40 setFixedSize(638, 392);
41 parentWidget()->setFixedSize(638,392);
46 void ViolaInstrument::setNotes(int array
[4])
48 array
[0] = 21; // 'A' string below middle c
49 array
[1] = 14; // 'D' string
50 array
[2] = 7; // 'G' string
51 array
[3] = 0; // 'C' string
56 CelloInstrument::CelloInstrument(QWidget
*parent
)
57 : StringInstrument(parent
)
61 // Set us up to look pretty
62 setPaletteBackgroundPixmap(QPixmap("cello.png"));
63 setFixedSize(639, 391);
64 parentWidget()->setFixedSize(639,391);
69 void CelloInstrument::setNotes(int array
[4])
71 array
[0] = 21; // 'A' string 2 below middle c
72 array
[1] = 14; // 'D' string
73 array
[2] = 7; // 'G' string
74 array
[3] = 0; // 'C' string
79 ContrabassInstrument::ContrabassInstrument(QWidget
*parent
)
80 : StringInstrument(parent
)
84 // Set us up to look pretty
85 setPaletteBackgroundPixmap(QPixmap("contrabass.png"));
86 setFixedSize(638, 388);
87 parentWidget()->setFixedSize(637,384);
92 void ContrabassInstrument::setNotes(int array
[4])
94 array
[0] = 19; // 'G' string 2 below middle c
95 array
[1] = 14; // 'D' string
96 array
[2] = 9; // 'A' string
97 array
[3] = 4; // 'E' string
102 /* StringInstrument */
104 /* For reference (Violin).. First line, note, second line key presses, third line, MIDI number
107 None 1 12 2 23 3 34 4
108 76 77 78 79 80 81 82 83
112 None TabQ Q W WE E ER R
113 69 70 71 72 73 74 75 76
117 None CapsA A S SD D DF F
118 62 63 64 65 66 67 68 69
122 None ShiftZ Z ZX X C CV V
123 55 56 57 58 59 60 61 62
127 StringInstrument::StringInstrument(QWidget
*parent
)
130 // Set all the keys to false
132 zeroArray(downFudge
);
134 zeroArray(oldVolume
);
142 StringInstrument::~StringInstrument()
146 QString
StringInstrument::generateHelp()
155 "<li>The row '1' '2' '3' '4' is the E string</li>"
156 "<li>The row 'q' 'w' 'e' 'r' is the A string</li>"
157 "<li>The row 'a' 's' 'd' 'f' is the D string</li>"
158 "<li>The row 'z' 'x' 'c' 'v' is the G string</li>"
159 "<li>The further to the right the key is, the higher the note</li>"
160 "<li>Try pressing multiple keys on the same string to get sharp notes. On the A,D,G strings try the Tab, Caps and Shift keys for sharp notes</li>"
165 "<li>Use the keys '7' '8' '9' '0' to bow the E string</li>"
166 "<li>Use the keys 'u' 'i' 'o' 'p' to bow the A string</li>"
167 "<li>Use the keys 'j' 'k' 'l' ';' to bow the D string</li>"
168 "<li>Use the keys 'm' ',' '.' '/' to bow the G string</li>"
169 "<li>The further right the key is, the quieter the note</li>"
177 void StringInstrument::paintEvent(QPaintEvent
*) {
178 QPainter
paint(this);
179 paint
.setPen(Qt::black
);
181 for(int i
= 0; i
< 4; i
++) {
183 text
+= "Playing note: ";
184 text
+= midi2string(note
[i
]);
185 text
+= " - Volume: " + QString::number(volume
[i
] / 30);
186 paint
.drawText(45, (i
+1)*20, text
);
190 void StringInstrument::keyPressEvent(QKeyEvent
*e
)
192 if(e
->isAutoRepeat() == true) {
199 // case Key_Tilde: // This is never used
200 // downFudge[0] = true;
269 // Bowing on volume 3 (max)
283 // Bowing on volume 2
297 // Bowing on volume 1
311 // Bowing on volume 0 (min)
335 QTimer::singleShot(50, this, SLOT(emitSounds()));
338 void StringInstrument::keyReleaseEvent(QKeyEvent
*e
)
340 if(e
->isAutoRepeat() == true) {
347 // case Key_Tilde: // This is never used
348 // downFudge[0] = true;
352 downFudge
[1] = false;
355 downFudge
[2] = false;
358 downFudge
[3] = false;
417 // Bowing on volume 3 (max)
431 // Bowing on volume 2
445 // Bowing on volume 1
459 // Bowing on volume 0 (min)
483 QTimer::singleShot(50, this, SLOT(emitSounds()));
486 void StringInstrument::zeroArray(bool array
[4][4])
488 for(int i
= 0; i
< 4; i
++) {
489 for(int j
= 0; j
< 4; j
++) {
495 void StringInstrument::zeroArray(bool array
[4])
497 for(int i
= 0; i
< 4; i
++) {
503 void StringInstrument::zeroArray(int array
[4])
505 for(int i
= 0; i
< 4; i
++) {
510 void StringInstrument::copyArray(int source
[4], int dest
[4])
512 for(int i
= 0; i
< 4; i
++) {
517 void StringInstrument::emitSounds()
519 copyArray(volume
, oldVolume
);
520 copyArray(note
, oldNote
);
523 copyArray(stringnote
, note
); // Fudge for setNotes(note);
525 // Need to find the differences in oldVolume, volume and oldNote, note
526 // Then stop changed notes, and start new ones
529 // Get the volumes, 'i' is the string, 'j' is the volume
531 for(i
= 0; i
< 4; i
++) {
532 for(int j
= 0; j
< 4; j
++) {
533 if(bow
[i
][j
] == true) {
534 volume
[i
] = (j
+ 1) * 30;
537 if(volume
[i
] != oldVolume
[i
]) { // The volume changed, stop that string
538 emit
stopNote(oldNote
[i
] + noteStart
);
539 oldNote
[i
] = -1; // Flag to restart, just in case the pitch didn't change
543 // Get the notes, 'i' is the string, 'j' is the volume
544 for(i
= 0; i
< 4; i
++) {
545 for(int j
= 0; j
< 4; j
++) {
546 if(down
[i
][j
] == false) {
549 note
[i
] = stringnote
[i
] + 2 * (j
+ 1);
550 for(int k
= stringnote
[i
]; k
<= note
[i
]; k
++) {
551 if(checkSharp(k
) == true) {
555 if(j
> 0 && down
[i
][j
] == true && down
[i
][j
-1] == true) {
558 else if(j
== 0 && downFudge
[i
] == true) {
562 if(note
[i
] != oldNote
[i
]) { // The pitch changed, restart the string
564 if(oldNote
[i
] != -1) {
565 emit
stopNote(oldNote
[i
] + noteStart
);
568 emit
playNote(note
[i
] + noteStart
, volume
[i
], 0);