Chris@885
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@885
|
2
|
Chris@885
|
3 /*
|
Chris@885
|
4 Sonic Visualiser
|
Chris@885
|
5 An audio file viewer and annotation editor.
|
Chris@885
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@885
|
7
|
Chris@885
|
8 This program is free software; you can redistribute it and/or
|
Chris@885
|
9 modify it under the terms of the GNU General Public License as
|
Chris@885
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@885
|
11 License, or (at your option) any later version. See the file
|
Chris@885
|
12 COPYING included with this distribution for more information.
|
Chris@885
|
13 */
|
Chris@885
|
14
|
Chris@885
|
15 #include "UnitConverter.h"
|
Chris@885
|
16
|
Chris@885
|
17 #include <QSpinBox>
|
Chris@885
|
18 #include <QComboBox>
|
Chris@885
|
19 #include <QDoubleSpinBox>
|
Chris@885
|
20 #include <QLabel>
|
Chris@885
|
21 #include <QDialogButtonBox>
|
Chris@885
|
22 #include <QGridLayout>
|
Chris@889
|
23 #include <QTabWidget>
|
Chris@885
|
24
|
Chris@885
|
25 #include "base/Debug.h"
|
Chris@885
|
26 #include "base/Pitch.h"
|
Chris@888
|
27 #include "base/Preferences.h"
|
Chris@885
|
28
|
Chris@885
|
29 using namespace std;
|
Chris@885
|
30
|
Chris@886
|
31 static QString pianoNotes[] = {
|
Chris@886
|
32 "C", "C# / Db", "D", "D# / Eb", "E",
|
Chris@886
|
33 "F", "F# / Gb", "G", "G# / Ab", "A", "A# / Bb", "B"
|
Chris@886
|
34 };
|
Chris@886
|
35
|
Chris@885
|
36 UnitConverter::UnitConverter(QWidget *parent) :
|
Chris@885
|
37 QDialog(parent)
|
Chris@885
|
38 {
|
Chris@889
|
39 QGridLayout *maingrid = new QGridLayout;
|
Chris@889
|
40 setLayout(maingrid);
|
Chris@889
|
41
|
Chris@889
|
42 QTabWidget *tabs = new QTabWidget;
|
Chris@889
|
43 maingrid->addWidget(tabs, 0, 0);
|
Chris@889
|
44
|
Chris@889
|
45 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close);
|
Chris@889
|
46 maingrid->addWidget(bb, 1, 0);
|
Chris@889
|
47 connect(bb, SIGNAL(rejected()), this, SLOT(close()));
|
Chris@889
|
48
|
Chris@889
|
49 QFrame *frame = new QFrame;
|
Chris@889
|
50 tabs->addTab(frame, tr("Pitch"));
|
Chris@889
|
51
|
Chris@885
|
52 QGridLayout *grid = new QGridLayout;
|
Chris@889
|
53 frame->setLayout(grid);
|
Chris@885
|
54
|
Chris@889
|
55 m_freq = new QDoubleSpinBox;
|
Chris@889
|
56 m_freq->setSuffix(QString(" Hz"));
|
Chris@889
|
57 m_freq->setDecimals(6);
|
Chris@889
|
58 m_freq->setMinimum(1e-3);
|
Chris@889
|
59 m_freq->setMaximum(1e6);
|
Chris@889
|
60 m_freq->setValue(440);
|
Chris@889
|
61 connect(m_freq, SIGNAL(valueChanged(double)),
|
Chris@889
|
62 this, SLOT(freqChanged(double)));
|
Chris@885
|
63
|
Chris@888
|
64 // The min and max range values for all the remaining controls are
|
Chris@888
|
65 // determined by the min and max Hz above
|
Chris@888
|
66
|
Chris@885
|
67 m_midi = new QSpinBox;
|
Chris@888
|
68 m_midi->setMinimum(-156);
|
Chris@888
|
69 m_midi->setMaximum(203);
|
Chris@885
|
70 connect(m_midi, SIGNAL(valueChanged(int)),
|
Chris@885
|
71 this, SLOT(midiChanged(int)));
|
Chris@885
|
72
|
Chris@885
|
73 m_note = new QComboBox;
|
Chris@886
|
74 for (int i = 0; i < 12; ++i) {
|
Chris@886
|
75 m_note->addItem(pianoNotes[i]);
|
Chris@886
|
76 }
|
Chris@886
|
77 connect(m_note, SIGNAL(currentIndexChanged(int)),
|
Chris@886
|
78 this, SLOT(noteChanged(int)));
|
Chris@885
|
79
|
Chris@885
|
80 m_octave = new QSpinBox;
|
Chris@888
|
81 m_octave->setMinimum(-14);
|
Chris@888
|
82 m_octave->setMaximum(15);
|
Chris@886
|
83 connect(m_octave, SIGNAL(valueChanged(int)),
|
Chris@886
|
84 this, SLOT(octaveChanged(int)));
|
Chris@885
|
85
|
Chris@885
|
86 m_cents = new QDoubleSpinBox;
|
Chris@885
|
87 m_cents->setSuffix(tr(" cents"));
|
Chris@885
|
88 m_cents->setDecimals(4);
|
Chris@885
|
89 m_cents->setMinimum(-50);
|
Chris@885
|
90 m_cents->setMaximum(50);
|
Chris@885
|
91 connect(m_cents, SIGNAL(valueChanged(double)),
|
Chris@885
|
92 this, SLOT(centsChanged(double)));
|
Chris@885
|
93
|
Chris@885
|
94 m_piano = new QSpinBox;
|
Chris@885
|
95 //!!!
|
Chris@885
|
96
|
Chris@886
|
97 int row = 1;
|
Chris@886
|
98
|
Chris@889
|
99 grid->addWidget(m_freq, row, 0, 2, 1);
|
Chris@889
|
100 grid->addWidget(new QLabel(tr("=")), row, 1, 2, 1);
|
Chris@885
|
101
|
Chris@889
|
102 grid->addWidget(new QLabel(tr("+")), row, 7, 2, 1);
|
Chris@889
|
103 grid->addWidget(m_cents, row, 8, 2, 1);
|
Chris@885
|
104
|
Chris@886
|
105 grid->addWidget(new QLabel(tr("Piano note")), row, 2, 1, 2);
|
Chris@886
|
106 grid->addWidget(m_note, row, 4);
|
Chris@886
|
107 grid->addWidget(new QLabel(tr("in octave")), row, 5);
|
Chris@886
|
108 grid->addWidget(m_octave, row, 6);
|
Chris@886
|
109
|
Chris@886
|
110 ++row;
|
Chris@886
|
111
|
Chris@888
|
112 grid->addWidget(new QLabel(tr("MIDI pitch")), row, 2, 1, 2);
|
Chris@886
|
113 grid->addWidget(m_midi, row, 4);
|
Chris@886
|
114
|
Chris@886
|
115 ++row;
|
Chris@885
|
116
|
Chris@891
|
117 m_pitchPrefsLabel = new QLabel;
|
Chris@891
|
118 grid->addWidget(m_pitchPrefsLabel, row, 0, 1, 9);
|
Chris@888
|
119
|
Chris@888
|
120 ++row;
|
Chris@888
|
121
|
Chris@888
|
122 grid->addWidget
|
Chris@888
|
123 (new QLabel(tr("Note that only pitches in the range 0 to 127 are valid "
|
Chris@888
|
124 "in the MIDI protocol.")),
|
Chris@888
|
125 row, 0, 1, 9);
|
Chris@888
|
126
|
Chris@888
|
127 ++row;
|
Chris@891
|
128
|
Chris@891
|
129 frame = new QFrame;
|
Chris@891
|
130 tabs->addTab(frame, tr("Tempo"));
|
Chris@891
|
131
|
Chris@891
|
132 grid = new QGridLayout;
|
Chris@891
|
133 frame->setLayout(grid);
|
Chris@885
|
134
|
Chris@891
|
135 connect(Preferences::getInstance(),
|
Chris@891
|
136 SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
|
Chris@891
|
137 this, SLOT(preferenceChanged(PropertyContainer::PropertyName)));
|
Chris@891
|
138
|
Chris@889
|
139 updatePitchesFromFreq();
|
Chris@891
|
140 updatePitchPrefsLabel();
|
Chris@891
|
141 updateTempiFromSamples();
|
Chris@885
|
142 }
|
Chris@885
|
143
|
Chris@885
|
144 UnitConverter::~UnitConverter()
|
Chris@885
|
145 {
|
Chris@885
|
146 }
|
Chris@885
|
147
|
Chris@885
|
148 void
|
Chris@891
|
149 UnitConverter::preferenceChanged(PropertyContainer::PropertyName)
|
Chris@891
|
150 {
|
Chris@891
|
151 updatePitchesFromFreq();
|
Chris@891
|
152 updatePitchPrefsLabel();
|
Chris@891
|
153 }
|
Chris@891
|
154
|
Chris@891
|
155 void
|
Chris@891
|
156 UnitConverter::updatePitchPrefsLabel()
|
Chris@891
|
157 {
|
Chris@891
|
158 m_pitchPrefsLabel->setText
|
Chris@891
|
159 (tr("With concert-A tuning frequency at %1 Hz, and "
|
Chris@891
|
160 "middle C residing in octave %2.\n"
|
Chris@891
|
161 "(These can be changed in the application preferences.)")
|
Chris@891
|
162 .arg(Preferences::getInstance()->getTuningFrequency())
|
Chris@891
|
163 .arg(Preferences::getInstance()->getOctaveOfMiddleC()));
|
Chris@891
|
164 }
|
Chris@891
|
165
|
Chris@891
|
166 void
|
Chris@889
|
167 UnitConverter::freqChanged(double freq)
|
Chris@885
|
168 {
|
Chris@889
|
169 cerr << "freqChanged: " << freq << endl;
|
Chris@889
|
170 updatePitchesFromFreq();
|
Chris@885
|
171 }
|
Chris@885
|
172
|
Chris@885
|
173 void
|
Chris@885
|
174 UnitConverter::midiChanged(int midi)
|
Chris@885
|
175 {
|
Chris@885
|
176 cerr << "midiChanged: " << midi << endl;
|
Chris@889
|
177 double freq = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value());
|
Chris@889
|
178 cerr << "freq -> " << freq << endl;
|
Chris@889
|
179 m_freq->setValue(freq);
|
Chris@885
|
180 }
|
Chris@885
|
181
|
Chris@885
|
182 void
|
Chris@885
|
183 UnitConverter::noteChanged(int note)
|
Chris@885
|
184 {
|
Chris@885
|
185 cerr << "noteChanged: " << note << endl;
|
Chris@887
|
186 int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(),
|
Chris@887
|
187 m_octave->value());
|
Chris@889
|
188 double freq = Pitch::getFrequencyForPitch(pitch, m_cents->value());
|
Chris@889
|
189 cerr << "freq -> " << freq << endl;
|
Chris@889
|
190 m_freq->setValue(freq);
|
Chris@885
|
191 }
|
Chris@885
|
192
|
Chris@885
|
193 void
|
Chris@885
|
194 UnitConverter::octaveChanged(int oct)
|
Chris@885
|
195 {
|
Chris@885
|
196 cerr << "octaveChanged: " << oct << endl;
|
Chris@888
|
197 int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(),
|
Chris@888
|
198 m_octave->value());
|
Chris@889
|
199 double freq = Pitch::getFrequencyForPitch(pitch, m_cents->value());
|
Chris@889
|
200 cerr << "freq -> " << freq << endl;
|
Chris@889
|
201 m_freq->setValue(freq);
|
Chris@885
|
202 }
|
Chris@885
|
203
|
Chris@885
|
204 void
|
Chris@885
|
205 UnitConverter::centsChanged(double cents)
|
Chris@885
|
206 {
|
Chris@885
|
207 cerr << "centsChanged: " << cents << endl;
|
Chris@889
|
208 double freq = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value());
|
Chris@889
|
209 cerr << "freq -> " << freq << endl;
|
Chris@889
|
210 m_freq->setValue(freq);
|
Chris@885
|
211 }
|
Chris@885
|
212
|
Chris@885
|
213 void
|
Chris@885
|
214 UnitConverter::pianoChanged(int piano)
|
Chris@885
|
215 {
|
Chris@885
|
216 cerr << "pianoChanged: " << piano << endl;
|
Chris@885
|
217 }
|
Chris@885
|
218
|
Chris@885
|
219 void
|
Chris@889
|
220 UnitConverter::updatePitchesFromFreq()
|
Chris@885
|
221 {
|
Chris@885
|
222 float cents = 0;
|
Chris@889
|
223 int pitch = Pitch::getPitchForFrequency(m_freq->value(), ¢s);
|
Chris@887
|
224 int note, octave;
|
Chris@887
|
225 Pitch::getNoteAndOctaveForPitch(pitch, note, octave);
|
Chris@885
|
226
|
Chris@888
|
227 cerr << "pitch " << pitch << " note " << note << " octave " << octave << " cents " << cents << endl;
|
Chris@888
|
228
|
Chris@885
|
229 m_midi->blockSignals(true);
|
Chris@885
|
230 m_cents->blockSignals(true);
|
Chris@887
|
231 m_note->blockSignals(true);
|
Chris@887
|
232 m_octave->blockSignals(true);
|
Chris@885
|
233
|
Chris@885
|
234 m_midi->setValue(pitch);
|
Chris@885
|
235 m_cents->setValue(cents);
|
Chris@887
|
236 m_note->setCurrentIndex(note);
|
Chris@887
|
237 m_octave->setValue(octave);
|
Chris@887
|
238
|
Chris@885
|
239 m_midi->blockSignals(false);
|
Chris@885
|
240 m_cents->blockSignals(false);
|
Chris@887
|
241 m_note->blockSignals(false);
|
Chris@887
|
242 m_octave->blockSignals(false);
|
Chris@885
|
243 }
|
Chris@885
|
244
|
Chris@891
|
245 void
|
Chris@891
|
246 UnitConverter::updateTempiFromSamples()
|
Chris@891
|
247 {
|
Chris@891
|
248 }
|
Chris@885
|
249
|
Chris@885
|
250
|