Initial commit
[virtualtones] / mainwin.cpp
1 // mainwin.cpp - Displays the MIDI keyboard and instrument selector
2 // Written by James Bunton <james@delx.cjb.net>
3 // Licensed under the GPL, see COPYING.txt for more details
4
5
6 #include "mainwin.h"
7
8
9 MainWin::MainWin()
10 : QWidget(0,0)
11 {
12 setCaption("Virtual Tones");
13
14 // Setup the MIDI output
15 midi = new MidiReal();
16 if(midi->initSuccess() == false) {
17 QMessageBox::critical(this, "MIDI Error", midi->getError());
18 qApp->quit();
19 exit(1);
20 }
21 midiFile = 0;
22
23 // Create the sound selector
24 soundSelection = new QComboBox(false, this);
25 QToolTip::add(soundSelection, "Select the MIDI instrument to play with");
26 fillSounds();
27 connect(soundSelection, SIGNAL(activated(int)), midi, SLOT(setInstrument(int)));
28 soundSelectionLabel = new QLabel("Sound:", this);
29
30 // Setup the interface selector
31 interfaceSelection = new QComboBox(false, this);
32 QToolTip::add(interfaceSelection, "Select the interface to play with");
33 interfaceSelection->insertItem("Piano", 0);
34 interfaceSelection->insertItem("Violin", 1);
35 interfaceSelection->insertItem("Viola", 2);
36 interfaceSelection->insertItem("Cello", 3);
37 interfaceSelection->insertItem("Contrabass", 4);
38 connect(interfaceSelection, SIGNAL(activated(int)), this, SLOT(interfaceSelectionSlot(int)));
39 instrument = 0;
40 interfaceSelectionLabel = new QLabel("Interface:", this);
41
42 // Setup the octave selector
43 octaveSelection = new QComboBox(false, this);
44 QToolTip::add(octaveSelection, "Select the starting octave");
45 for(int i = 0; i < 11; i++) {
46 octaveSelection->insertItem("Octave " + QString::number(i - 2), i);
47 }
48 octaveSelectionLabel = new QLabel("Base Octave:", this);
49
50 // Create the help & quit button
51 helpBtn = new QPushButton("Help", this);
52 quitBtn = new QPushButton("Quit", this);
53 connect(quitBtn, SIGNAL(clicked()), qApp, SLOT(quit()));
54
55 // MIDI recording buttons
56 recordBtn = new QPushButton("Record", this);
57 QToolTip::add(recordBtn, "Starts a MIDI recording of the notes played");
58 recordBtn->setEnabled(true);
59 connect(recordBtn, SIGNAL(clicked()), SLOT(setupRecord()));
60 stopBtn = new QPushButton("Stop", this);
61 QToolTip::add(stopBtn, "Stops the MIDI recording");
62 stopBtn->setEnabled(false);
63 connect(stopBtn, SIGNAL(clicked()), SLOT(finishRecord()));
64
65
66 // The about label
67 aboutLabel = new QLabel("Written for Julieanne...", this);
68
69 // Setup the layouts
70 soundSelectionLayout = new QVBoxLayout();
71 soundSelectionLayout->addWidget(soundSelectionLabel);
72 soundSelectionLayout->addWidget(soundSelection);
73
74 interfaceSelectionLayout = new QVBoxLayout();
75 interfaceSelectionLayout->addWidget(interfaceSelectionLabel);
76 interfaceSelectionLayout->addWidget(interfaceSelection);
77
78 octaveSelectionLayout = new QVBoxLayout();
79 octaveSelectionLayout->addWidget(octaveSelectionLabel);
80 octaveSelectionLayout->addWidget(octaveSelection);
81
82 midiBtnLayout = new QVBoxLayout();
83 midiBtnLayout->addWidget(recordBtn);
84 midiBtnLayout->addSpacing(5);
85 midiBtnLayout->addWidget(stopBtn);
86
87 buttonsLayout = new QVBoxLayout();
88 buttonsLayout->addWidget(helpBtn);
89 buttonsLayout->addSpacing(5);
90 buttonsLayout->addWidget(quitBtn);
91
92 optionsLayout = new QHBoxLayout();
93 optionsLayout->addSpacing(5);
94 optionsLayout->addLayout(interfaceSelectionLayout);
95 optionsLayout->addSpacing(5);
96 optionsLayout->addLayout(soundSelectionLayout);
97 optionsLayout->addSpacing(5);
98 optionsLayout->addLayout(octaveSelectionLayout);
99 optionsLayout->addSpacing(5);
100 optionsLayout->addLayout(midiBtnLayout);
101 optionsLayout->addSpacing(5);
102 optionsLayout->addLayout(buttonsLayout);
103 optionsLayout->addSpacing(5);
104
105 vLayout = new QVBoxLayout(this);
106 vLayout->insertSpacing(0, 5);
107 vLayout->insertLayout(1, optionsLayout);
108 vLayout->insertSpacing(2, 5);
109 vLayout->insertSpacing(3, 1);// instrument goes here
110 vLayout->insertSpacing(4, 5);
111 vLayout->insertWidget(5, aboutLabel);
112 vLayout->insertSpacing(6, 5);
113
114 interfaceSelectionSlot(0);
115
116 show();
117 }
118
119 MainWin::~MainWin()
120 {
121 delete midi;
122 if(midiFile != 0)
123 delete midiFile;
124 }
125
126 void MainWin::setupRecord() {
127 if(midiFile == 0) {
128 QString filename = QFileDialog::getSaveFileName(QString::null, "MIDI files (*.mid *.midi)", this);
129 if(filename.isNull() || filename.isEmpty())
130 return;
131 midiFile = new MidiFile(filename);
132 if(midiFile->initSuccess() == false) {
133 QMessageBox::warning(this, "MIDI recording error", midiFile->getError());
134 delete midiFile;
135 return;
136 }
137 connect(soundSelection, SIGNAL(activated(int)), midiFile, SLOT(setInstrument(int)));
138 connect(instrument, SIGNAL(playNote(int, int, int)), midiFile, SLOT(playNote(int, int, int)));
139 connect(instrument, SIGNAL(stopNote(int)), midiFile, SLOT(stopNote(int)));
140 }
141
142 recordBtn->setEnabled(false);
143 stopBtn->setEnabled(true);
144 }
145
146 void MainWin::finishRecord() {
147 if(midiFile != 0) {
148 delete midiFile;
149 midiFile = 0;
150 }
151
152 recordBtn->setEnabled(true);
153 stopBtn->setEnabled(false);
154 }
155
156 void MainWin::interfaceSelectionSlot(int num)
157 {
158 // Right now interfaces 0-4 exist
159
160 if(instrument != 0) {
161 // if(vLayout->findWidget(instrument)) {
162 // vLayout->remove(instrument);
163 // }
164 delete instrument;
165 instrument = 0;
166 }
167
168 switch(num) {
169 // Create the instrument
170
171 default:
172 case 0: {
173 PianoInstrument *p = new PianoInstrument(this);
174 instrument = p;
175 // Select piano as the default
176 soundSelection->setCurrentItem(0);
177 midi->setInstrument(0);
178 if(midiFile != 0)
179 midiFile->setInstrument(0);
180 break;
181 }
182 case 1: {
183 ViolinInstrument *p = new ViolinInstrument(this);
184 instrument = p;
185 // Select violin as the default
186 soundSelection->setCurrentItem(40);
187 midi->setInstrument(40);
188 if(midiFile != 0)
189 midiFile->setInstrument(40);
190 break;
191 }
192 case 2: {
193 ViolaInstrument *p = new ViolaInstrument(this);
194 instrument = p;
195 // Select violin as the default
196 soundSelection->setCurrentItem(41);
197 midi->setInstrument(41);
198 if(midiFile != 0)
199 midiFile->setInstrument(41);
200 break;
201 }
202 case 3: {
203 CelloInstrument *p = new CelloInstrument(this);
204 instrument = p;
205 // Select violin as the default
206 soundSelection->setCurrentItem(42);
207 midi->setInstrument(42);
208 if(midiFile != 0)
209 midiFile->setInstrument(42);
210 break;
211 }
212 case 4: {
213 ContrabassInstrument *p = new ContrabassInstrument(this);
214 instrument = p;
215 // Select violin as the default
216 soundSelection->setCurrentItem(43);
217 midi->setInstrument(43);
218 if(midiFile != 0)
219 midiFile->setInstrument(43);
220 break;
221 }
222 }
223
224 // Relayout
225 vLayout->insertWidget(3, instrument);
226 instrument->show();
227
228 // Connect signals
229 connect(instrument, SIGNAL(playNote(int, int, int)), midi, SLOT(playNote(int, int, int)));
230 connect(instrument, SIGNAL(stopNote(int)), midi, SLOT(stopNote(int)));
231 if(midiFile != 0) {
232 connect(instrument, SIGNAL(playNote(int, int, int)), midiFile, SLOT(playNote(int, int, int)));
233 connect(instrument, SIGNAL(stopNote(int)), midiFile, SLOT(stopNote(int)));
234 }
235 connect(helpBtn, SIGNAL(clicked()), instrument, SLOT(displayHelp()));
236 connect(octaveSelection, SIGNAL(activated(int)), instrument, SLOT(setStartOctave(int)));
237
238 // Set the octave widget
239 octaveSelection->setCurrentItem(instrument->getNoteStart() / 12);
240 }
241
242 void MainWin::fillSounds()
243 {
244 soundSelection->insertItem("Acoustic Grand Piano", 0);
245 soundSelection->insertItem("Bright Acoustic Piano", 1);
246 soundSelection->insertItem("Electric Grand Piano", 2);
247 soundSelection->insertItem("Honky-tonk Piano", 3);
248 soundSelection->insertItem("Rhodes Piano", 4);
249 soundSelection->insertItem("Chorused Piano", 5);
250 soundSelection->insertItem("Harpsichord", 6);
251 soundSelection->insertItem("Clavinet", 7);
252 soundSelection->insertItem("Celesta", 8);
253 soundSelection->insertItem("Glockenspiel", 9);
254 soundSelection->insertItem("Music Box", 10);
255 soundSelection->insertItem("Vibraphone", 11);
256 soundSelection->insertItem("Marimba", 12);
257 soundSelection->insertItem("Xylophone", 13);
258 soundSelection->insertItem("Tubular bells", 14);
259 soundSelection->insertItem("Dulcimer", 15);
260 soundSelection->insertItem("Draw Organ", 16);
261 soundSelection->insertItem("Percussive Organ", 17);
262 soundSelection->insertItem("Rock Organ", 18);
263 soundSelection->insertItem("Church Organ", 19);
264 soundSelection->insertItem("Reed Organ", 20);
265 soundSelection->insertItem("Accordion", 21);
266 soundSelection->insertItem("Harmonica", 22);
267 soundSelection->insertItem("Tango Accordion", 23);
268 soundSelection->insertItem("Acoustic Nylon Guitar", 24);
269 soundSelection->insertItem("Acoustic Steel Guitar", 25);
270 soundSelection->insertItem("Electric Jazz Guitar", 26);
271 soundSelection->insertItem("Electric clean Guitar", 27);
272 soundSelection->insertItem("Electric Guitar muted", 28);
273 soundSelection->insertItem("Overdriven Guitar", 29);
274 soundSelection->insertItem("Distortion Guitar", 30);
275 soundSelection->insertItem("Guitar Harmonics", 31);
276 soundSelection->insertItem("Wood Bass", 32);
277 soundSelection->insertItem("Electric Bass Fingered", 33);
278 soundSelection->insertItem("Electric Bass Picked", 34);
279 soundSelection->insertItem("Fretless Bass", 35);
280 soundSelection->insertItem("Slap Bass 1", 36);
281 soundSelection->insertItem("Slap Bass 2", 37);
282 soundSelection->insertItem("Synth Bass 1", 38);
283 soundSelection->insertItem("Synth Bass 2", 39);
284 soundSelection->insertItem("Violin", 40);
285 soundSelection->insertItem("Viola", 41);
286 soundSelection->insertItem("Cello", 42);
287 soundSelection->insertItem("Contrabass", 43);
288 soundSelection->insertItem("Tremolo Strings", 44);
289 soundSelection->insertItem("Pizzicato Strings", 45);
290 soundSelection->insertItem("Orchestral Harp", 46);
291 soundSelection->insertItem("Timpani", 47);
292 soundSelection->insertItem("Acoustic String Ensemble 1", 48);
293 soundSelection->insertItem("Acoustic String Ensemble 2", 49);
294 soundSelection->insertItem("Synth Strings 1", 50);
295 soundSelection->insertItem("Synth Strings 2", 51);
296 soundSelection->insertItem("Aah Choir", 52);
297 soundSelection->insertItem("Ooh Choir", 53);
298 soundSelection->insertItem("Synvox", 54);
299 soundSelection->insertItem("Orchestra Hit", 55);
300 soundSelection->insertItem("Trumpet", 56);
301 soundSelection->insertItem("Trombone", 57);
302 soundSelection->insertItem("Tuba", 58);
303 soundSelection->insertItem("Muted Trumpet", 59);
304 soundSelection->insertItem("French Horn", 60);
305 soundSelection->insertItem("Brass Section", 61);
306 soundSelection->insertItem("Synth Brass 1", 62);
307 soundSelection->insertItem("Synth Brass 2", 63);
308 soundSelection->insertItem("Soprano Sax", 64);
309 soundSelection->insertItem("Alto Sax", 65);
310 soundSelection->insertItem("Tenor Sax", 66);
311 soundSelection->insertItem("Baritone Sax", 67);
312 soundSelection->insertItem("Oboe", 68);
313 soundSelection->insertItem("English Horn", 69);
314 soundSelection->insertItem("Bassoon", 70);
315 soundSelection->insertItem("Clarinet", 71);
316 soundSelection->insertItem("Piccolo", 72);
317 soundSelection->insertItem("Flute", 73);
318 soundSelection->insertItem("Recorder", 74);
319 soundSelection->insertItem("Pan Flute", 75);
320 soundSelection->insertItem("Bottle blow", 76);
321 soundSelection->insertItem("Shakuhachi", 77);
322 soundSelection->insertItem("Whistle", 78);
323 soundSelection->insertItem("Ocarina", 79);
324 soundSelection->insertItem("Square Lead", 80);
325 soundSelection->insertItem("Saw Lead", 81);
326 soundSelection->insertItem("Calliope", 82);
327 soundSelection->insertItem("Chiffer", 83);
328 soundSelection->insertItem("Synth Lead 5", 84);
329 soundSelection->insertItem("Synth Lead 6", 85);
330 soundSelection->insertItem("Synth Lead 7", 86);
331 soundSelection->insertItem("Synth Lead 8", 87);
332 soundSelection->insertItem("Synth Pad 1", 88);
333 soundSelection->insertItem("Synth Pad 2", 89);
334 soundSelection->insertItem("Synth Pad 3", 90);
335 soundSelection->insertItem("Synth Pad 4", 91);
336 soundSelection->insertItem("Synth Pad 5", 92);
337 soundSelection->insertItem("Synth Pad 6", 93);
338 soundSelection->insertItem("Synth Pad 7", 94);
339 soundSelection->insertItem("Synth Pad 8", 95);
340 soundSelection->insertItem("Ice Rain", 96);
341 soundSelection->insertItem("Soundtracks", 97);
342 soundSelection->insertItem("Crystal", 98);
343 soundSelection->insertItem("Atmosphere", 99);
344 soundSelection->insertItem("Bright", 100);
345 soundSelection->insertItem("Goblin", 101);
346 soundSelection->insertItem("Echoes", 102);
347 soundSelection->insertItem("Space", 103);
348 soundSelection->insertItem("Sitar", 104);
349 soundSelection->insertItem("Banjo", 105);
350 soundSelection->insertItem("Shamisen", 106);
351 soundSelection->insertItem("Koto", 107);
352 soundSelection->insertItem("Kalimba", 108);
353 soundSelection->insertItem("Bagpipe", 109);
354 soundSelection->insertItem("Fiddle", 110);
355 soundSelection->insertItem("Shanai", 111);
356 soundSelection->insertItem("Tinkle bell", 112);
357 soundSelection->insertItem("Agogo", 113);
358 soundSelection->insertItem("Steel Drums", 114);
359 soundSelection->insertItem("Woodblock", 115);
360 soundSelection->insertItem("Taiko Drum", 116);
361 soundSelection->insertItem("Melodic Tom", 117);
362 soundSelection->insertItem("Synth Tom", 118);
363 soundSelection->insertItem("Reverse Cymbal", 119);
364 soundSelection->insertItem("Guitar Fret Noise", 120);
365 soundSelection->insertItem("Breath Noise", 121);
366 soundSelection->insertItem("Seashore", 122);
367 soundSelection->insertItem("Bird Tweet", 123);
368 soundSelection->insertItem("Telephone Ring", 124);
369 soundSelection->insertItem("Helicopter", 125);
370 soundSelection->insertItem("Applause", 126);
371 soundSelection->insertItem("Gunshot", 127);
372
373 }
374