1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Rosegarden
5 A MIDI and audio sequencer and musical notation editor.
6 Copyright 2000-2009 the Rosegarden development team.
7
8 Other copyrights also apply to some parts of this work. Please
9 see the AUTHORS file and individual file headers for details.
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version. See the file
15 COPYING included with this distribution for more information.
16 */
17
18
19 #include "PitchTrackerConfigurationPage.h"
20 #include "sound/Tuning.h"
21 #include "sound/PitchDetector.h"
22 #include "misc/ConfigGroups.h"
23 #include "misc/Debug.h"
24 // Might need default analysis sizes
25 #include "gui/configuration/PitchTrackerConfigurationPage.h"
26 #include "sound/PitchDetector.h"
27 // Tunings are returned a stl vector. See sound/Tuning.h
28 #include <vector>
29 #include <QLabel>
30 #include <QComboBox>
31 #include <QSpinBox>
32 #include <QCheckBox>
33 #include <QSettings>
34 #include <QWidget>
35 #include <QHBoxLayout>
36 #include <QToolTip>
37 #include <QLayout>
38
39 namespace Rosegarden
40 {
41
42 const int PitchTrackerConfigurationPage::defaultGraphWidth = 4000;
43 const int PitchTrackerConfigurationPage::defaultGraphHeight = 100;
44 const bool PitchTrackerConfigurationPage::defaultIgnore8ve = true;
45
PitchTrackerConfigurationPage(QWidget * parent)46 PitchTrackerConfigurationPage::PitchTrackerConfigurationPage(QWidget *parent) :
47 TabbedConfigurationPage(parent),
48 m_noTuningsAlert(parent)
49 {
50 QSettings settings;
51 settings.beginGroup(PitchTrackerConfigGroup);
52
53 QFrame *frame;
54 QGridLayout *layout;
55
56 frame = new QFrame(m_tabWidget);
57 frame->setContentsMargins(10, 10, 10, 10);
58 layout = new QGridLayout(frame);
59 layout->setSpacing(5);
60
61 int row = 0;
62
63 layout->setRowMinimumHeight(row, 15);
64 ++row;
65
66 layout->addWidget(new QLabel(tr("Tuning"), frame), row, 0);
67
68 m_tuningMode = new QComboBox(frame);
69 connect(m_tuningMode, SIGNAL(activated(int)),
70 this, SLOT(slotModified()));
71 m_tuningMode->setEditable(false);
72
73 slotPopulateTuningCombo(true);
74
75 int defaultTuningMode = settings.value("tuning", 0).toInt() ;
76 m_tuningMode->setCurrentIndex(defaultTuningMode);
77 layout->addWidget(m_tuningMode, row, 1, 1, 2);
78 ++row;
79
80 // TODO: write Edit Tuning dialogue to allow these to be edited
81 // Currently, the settings make A440 in MIDI 12ET be the same note
82 // in all tunings (a regression since rosegarden v1.2.4gpt1)
83 m_rootPitch = 69;
84 m_refPitch = 69;
85 m_refFreq = 440.0;
86 layout->addWidget(new QLabel(tr("Root Pitch"), frame), row, 0);
87 m_rootPitchLabel = new QLabel("A3");
88 layout->addWidget(m_rootPitchLabel, row, 1, 1, 2);
89 row++;
90 layout->addWidget(new QLabel(tr("Reference Pitch"), frame), row, 0);
91 m_refPitchLabel = new QLabel("A3");
92 layout->addWidget(m_refPitchLabel, row, 1, 1, 2);
93 row++;
94 layout->addWidget(new QLabel(tr("Reference Frequency"), frame), row, 0);
95 m_refFreqLabel = new QLabel("440.0");
96 layout->addWidget(m_refFreqLabel, row, 1, 1, 2);
97 row++;
98
99 layout->setRowStretch(row, 2);
100 frame->setLayout(layout);
101 addTab(frame, tr("General"));
102
103 frame = new QFrame(m_tabWidget);
104 frame->setContentsMargins(10, 10, 10, 10);
105 layout = new QGridLayout(frame);
106 layout->setSpacing(5);
107 row = 0;
108
109 // TODO: Add input source combo
110 layout->addWidget(new QLabel(tr("Method"), frame), row, 0);
111 m_method = new QComboBox(frame);
112 connect(m_method, SIGNAL(activated(int)),
113 this, SLOT(slotModified()));
114 m_method->setEditable(false);
115 const QVector<PitchDetector::Method> *pt_methods =
116 PitchDetector::getMethods();
117 if (pt_methods) {
118 QVector<PitchDetector::Method>::const_iterator i;
119 for (i = pt_methods->begin(); i != pt_methods->end(); ++i) {
120 m_method->addItem(*i);
121 }
122 int defaultMethod = settings.value("method", 0).toInt() ;
123 if (defaultMethod >= 0 && defaultMethod < pt_methods->size()) {
124 m_method->setCurrentIndex(defaultMethod);
125 }
126 }
127 layout->addWidget(m_method, row, 1, 1, 2);
128 ++row;
129
130 layout->addWidget(new QLabel(tr("Frame Size"), frame), row, 0);
131 m_frameSize = new QSpinBox(frame);
132 connect(m_frameSize, SIGNAL(valueChanged(int)),
133 this, SLOT(slotModified()));
134 m_frameSize->setMinimum(64);
135 m_frameSize->setMaximum(32768);
136 int frameSize = settings.value("framesize",
137 PitchDetector::defaultFrameSize).toInt();
138 if (frameSize >= 64 && frameSize <= 32768) {
139 m_frameSize->setValue(frameSize);
140 }
141 layout->addWidget(m_frameSize, row, 1, 1, 2);
142 ++row;
143
144 layout->addWidget(new QLabel(tr("Step Size"), frame), row, 0);
145 m_stepSize = new QSpinBox(frame);
146 connect(m_stepSize, SIGNAL(valueChanged(int)),
147 this, SLOT(slotModified()));
148 m_stepSize->setMinimum(64);
149 m_stepSize->setMaximum(8192);
150 int stepSize = settings.value("stepsize",
151 PitchDetector::defaultStepSize).toInt();
152 if (stepSize >= 64 && stepSize <= 8192) {
153 m_stepSize->setValue(stepSize);
154 }
155 layout->addWidget(m_stepSize, row, 1, 1, 2);
156 ++row;
157
158 layout->addWidget(new QLabel(tr("Ignore Octave Errors"), frame), row, 0);
159 m_ignore8ve = new QCheckBox(frame);
160 connect(m_ignore8ve, &QCheckBox::stateChanged,
161 this, &PitchTrackerConfigurationPage::slotModified);
162 bool defaultIgnore8ve =
163 settings.value("ignoreoctave",
164 PitchTrackerConfigurationPage::defaultIgnore8ve
165 ).toBool();
166 m_ignore8ve->setChecked(defaultIgnore8ve);
167 layout->addWidget(m_ignore8ve, row, 1, 1, 2);
168 ++row;
169
170 layout->setRowStretch(row, 2);
171 frame->setLayout(layout);
172 addTab(frame, tr("Algorithm"));
173
174 frame = new QFrame(m_tabWidget);
175 frame->setContentsMargins(10, 10, 10, 10);
176 layout = new QGridLayout(frame);
177 layout->setSpacing(5);
178 row = 0;
179 layout->addWidget(new QLabel(tr("Graph Width (ms)"), frame), row, 0);
180 m_graphWidth = new QSpinBox(frame);
181 connect(m_graphWidth, SIGNAL(valueChanged(int)),
182 this, SLOT(slotModified()));
183 m_graphWidth->setMinimum(200);
184 m_graphWidth->setMaximum(20000);
185 const int graphWidth =
186 settings.value("graphwidth", defaultGraphWidth).toInt();
187 if (graphWidth >= 200 && graphWidth <= 20000) {
188 m_graphWidth->setValue(graphWidth);
189 }
190 layout->addWidget(m_graphWidth, row, 1, 1, 2);
191 ++row;
192
193 layout->addWidget(new QLabel(tr("Graph Height (cents)"), frame), row, 0);
194 m_graphHeight = new QSpinBox(frame);
195 connect(m_graphHeight, SIGNAL(valueChanged(int)),
196 this, SLOT(slotModified()));
197 m_graphHeight->setMinimum(20);
198 m_graphHeight->setMaximum(600);
199 const int graphHeight =
200 settings.value("graphheight", defaultGraphHeight).toInt();
201 if (graphHeight >= 20 && graphHeight <= 600) {
202 m_graphHeight->setValue(graphHeight);
203 }
204 layout->addWidget(m_graphHeight, row, 1, 1, 2);
205 ++row;
206
207 layout->setRowStretch(row, 2);
208 frame->setLayout(layout);
209 addTab(frame, tr("Appearance"));
210 settings.endGroup();
211 }
212
213 void
slotPopulateTuningCombo(bool rescan)214 PitchTrackerConfigurationPage::slotPopulateTuningCombo(bool rescan)
215 {
216 // Read the tunings file to determine those available, and populate the
217 // combo box.
218 if (rescan || !m_tunings) m_tunings = Accidentals::Tuning::getTunings();
219
220 if (m_tunings) {
221 // Empty the tuning mode combo box and repopulate.
222 while (m_tuningMode->count()) {
223 m_tuningMode->removeItem(0);
224 }
225
226 std::vector<Accidentals::Tuning *>::iterator t;
227 for (t = m_tunings->begin(); t != m_tunings->end(); ++t) {
228 m_tuningMode->addItem(QString((*t)->getName().c_str()));
229 }
230 } else { // the tunings file couldn't be found, so display a message
231 RG_WARNING << "Pitch Tracker: Error: No tunings!!\n"
232 "Probably a missing tuning.xml file.\n"
233 "The user will have been warned.";
234
235 m_noTuningsAlert.showMessage(tr(
236 "The tunings file could not be found! "
237 "The file named \"tunings.xml\" containing tuning definitions "
238 "has not been found in any of the standard "
239 "directories. On Linux platforms, these include "
240 "/usr/share/rosegarden/pitches, "
241 "/usr/local/share/rosegarden/pitches and "
242 "$HOME/.local/share/rosegarden/pitches. "
243 "This file should be part of the standard installation."));
244 }
245 }
246
247 void
apply()248 PitchTrackerConfigurationPage::apply()
249 {
250 QSettings settings;
251 settings.beginGroup(PitchTrackerConfigGroup);
252
253 settings.setValue("tuning", m_tuningMode->currentIndex());
254 settings.setValue("rootpitch", "A3");
255 settings.setValue("refpitch", "A3");
256 settings.setValue("reffrequency", 440.0);
257 settings.setValue("method", m_method->currentIndex());
258 settings.setValue("framesize", m_frameSize->value());
259 settings.setValue("stepsize", m_stepSize->value());
260 settings.setValue("ignoreoctave", m_ignore8ve->isChecked());
261 settings.setValue("graphwidth", m_graphWidth->value());
262 settings.setValue("graphheight", m_graphHeight->value());
263
264 settings.endGroup();
265 }
266
267 }
268