Chris@885: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@885: Chris@885: /* Chris@885: Sonic Visualiser Chris@885: An audio file viewer and annotation editor. Chris@885: Centre for Digital Music, Queen Mary, University of London. Chris@885: Chris@885: This program is free software; you can redistribute it and/or Chris@885: modify it under the terms of the GNU General Public License as Chris@885: published by the Free Software Foundation; either version 2 of the Chris@885: License, or (at your option) any later version. See the file Chris@885: COPYING included with this distribution for more information. Chris@885: */ Chris@885: Chris@885: #include "UnitConverter.h" Chris@885: Chris@885: #include Chris@885: #include Chris@885: #include Chris@885: #include Chris@885: #include Chris@885: #include Chris@885: Chris@885: #include "base/Debug.h" Chris@885: #include "base/Pitch.h" Chris@888: #include "base/Preferences.h" Chris@885: Chris@885: using namespace std; Chris@885: Chris@886: static QString pianoNotes[] = { Chris@886: "C", "C# / Db", "D", "D# / Eb", "E", Chris@886: "F", "F# / Gb", "G", "G# / Ab", "A", "A# / Bb", "B" Chris@886: }; Chris@886: Chris@885: UnitConverter::UnitConverter(QWidget *parent) : Chris@885: QDialog(parent) Chris@885: { Chris@885: QGridLayout *grid = new QGridLayout; Chris@885: setLayout(grid); Chris@885: Chris@885: m_hz = new QDoubleSpinBox; Chris@885: m_hz->setSuffix(QString(" Hz")); Chris@885: m_hz->setDecimals(6); Chris@888: m_hz->setMinimum(1e-3); Chris@885: m_hz->setMaximum(1e6); Chris@885: m_hz->setValue(440); Chris@885: connect(m_hz, SIGNAL(valueChanged(double)), Chris@885: this, SLOT(hzChanged(double))); Chris@885: Chris@888: // The min and max range values for all the remaining controls are Chris@888: // determined by the min and max Hz above Chris@888: Chris@885: m_midi = new QSpinBox; Chris@888: m_midi->setMinimum(-156); Chris@888: m_midi->setMaximum(203); Chris@885: connect(m_midi, SIGNAL(valueChanged(int)), Chris@885: this, SLOT(midiChanged(int))); Chris@885: Chris@885: m_note = new QComboBox; Chris@886: for (int i = 0; i < 12; ++i) { Chris@886: m_note->addItem(pianoNotes[i]); Chris@886: } Chris@886: connect(m_note, SIGNAL(currentIndexChanged(int)), Chris@886: this, SLOT(noteChanged(int))); Chris@885: Chris@885: m_octave = new QSpinBox; Chris@888: m_octave->setMinimum(-14); Chris@888: m_octave->setMaximum(15); Chris@886: connect(m_octave, SIGNAL(valueChanged(int)), Chris@886: this, SLOT(octaveChanged(int))); Chris@885: Chris@885: m_cents = new QDoubleSpinBox; Chris@885: m_cents->setSuffix(tr(" cents")); Chris@885: m_cents->setDecimals(4); Chris@885: m_cents->setMinimum(-50); Chris@885: m_cents->setMaximum(50); Chris@885: connect(m_cents, SIGNAL(valueChanged(double)), Chris@885: this, SLOT(centsChanged(double))); Chris@885: Chris@885: m_piano = new QSpinBox; Chris@885: //!!! Chris@885: Chris@886: int row = 1; Chris@886: Chris@886: grid->addWidget(m_hz, row, 0); Chris@886: grid->addWidget(new QLabel(tr("=")), row, 1); Chris@885: Chris@886: grid->addWidget(new QLabel(tr("+")), row, 7); Chris@886: grid->addWidget(m_cents, row, 8); Chris@885: Chris@886: grid->addWidget(new QLabel(tr("Piano note")), row, 2, 1, 2); Chris@886: grid->addWidget(m_note, row, 4); Chris@886: grid->addWidget(new QLabel(tr("in octave")), row, 5); Chris@886: grid->addWidget(m_octave, row, 6); Chris@886: Chris@886: ++row; Chris@886: Chris@888: grid->addWidget(new QLabel(tr("MIDI pitch")), row, 2, 1, 2); Chris@886: grid->addWidget(m_midi, row, 4); Chris@886: Chris@886: ++row; Chris@885: Chris@888: grid->addWidget Chris@888: (new QLabel(tr("With concert A tuning frequency at %1 Hz, and " Chris@888: "middle C residing in octave %2.\n" Chris@888: "(These can be changed in the application preferences.)") Chris@888: .arg(Preferences::getInstance()->getTuningFrequency()) Chris@888: .arg(Preferences::getInstance()->getOctaveOfMiddleC())), Chris@888: row, 0, 1, 9); Chris@888: Chris@888: ++row; Chris@888: Chris@888: grid->addWidget Chris@888: (new QLabel(tr("Note that only pitches in the range 0 to 127 are valid " Chris@888: "in the MIDI protocol.")), Chris@888: row, 0, 1, 9); Chris@888: Chris@888: ++row; Chris@888: Chris@885: QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close); Chris@886: grid->addWidget(bb, row, 0, 1, 9); Chris@885: connect(bb, SIGNAL(rejected()), this, SLOT(close())); Chris@885: Chris@885: updateAllFromHz(); Chris@885: } Chris@885: Chris@885: UnitConverter::~UnitConverter() Chris@885: { Chris@885: } Chris@885: Chris@885: void Chris@885: UnitConverter::hzChanged(double hz) Chris@885: { Chris@885: cerr << "hzChanged: " << hz << endl; Chris@885: updateAllFromHz(); Chris@885: } Chris@885: Chris@885: void Chris@885: UnitConverter::midiChanged(int midi) Chris@885: { Chris@885: cerr << "midiChanged: " << midi << endl; Chris@888: double hz = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value()); Chris@888: cerr << "hz -> " << hz << endl; Chris@888: m_hz->setValue(hz); Chris@885: } Chris@885: Chris@885: void Chris@885: UnitConverter::noteChanged(int note) Chris@885: { Chris@885: cerr << "noteChanged: " << note << endl; Chris@887: int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(), Chris@887: m_octave->value()); Chris@888: double hz = Pitch::getFrequencyForPitch(pitch, m_cents->value()); Chris@888: cerr << "hz -> " << hz << endl; Chris@888: m_hz->setValue(hz); Chris@885: } Chris@885: Chris@885: void Chris@885: UnitConverter::octaveChanged(int oct) Chris@885: { Chris@885: cerr << "octaveChanged: " << oct << endl; Chris@888: int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(), Chris@888: m_octave->value()); Chris@888: double hz = Pitch::getFrequencyForPitch(pitch, m_cents->value()); Chris@888: cerr << "hz -> " << hz << endl; Chris@888: m_hz->setValue(hz); Chris@885: } Chris@885: Chris@885: void Chris@885: UnitConverter::centsChanged(double cents) Chris@885: { Chris@885: cerr << "centsChanged: " << cents << endl; Chris@888: double hz = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value()); Chris@888: cerr << "hz -> " << hz << endl; Chris@888: m_hz->setValue(hz); Chris@885: } Chris@885: Chris@885: void Chris@885: UnitConverter::pianoChanged(int piano) Chris@885: { Chris@885: cerr << "pianoChanged: " << piano << endl; Chris@885: } Chris@885: Chris@885: void Chris@885: UnitConverter::updateAllFromHz() Chris@885: { Chris@885: float cents = 0; Chris@885: int pitch = Pitch::getPitchForFrequency(m_hz->value(), ¢s); Chris@887: int note, octave; Chris@887: Pitch::getNoteAndOctaveForPitch(pitch, note, octave); Chris@885: Chris@888: cerr << "pitch " << pitch << " note " << note << " octave " << octave << " cents " << cents << endl; Chris@888: Chris@885: m_midi->blockSignals(true); Chris@885: m_cents->blockSignals(true); Chris@887: m_note->blockSignals(true); Chris@887: m_octave->blockSignals(true); Chris@885: Chris@885: m_midi->setValue(pitch); Chris@885: m_cents->setValue(cents); Chris@887: m_note->setCurrentIndex(note); Chris@887: m_octave->setValue(octave); Chris@887: Chris@885: m_midi->blockSignals(false); Chris@885: m_cents->blockSignals(false); Chris@887: m_note->blockSignals(false); Chris@887: m_octave->blockSignals(false); Chris@885: } Chris@885: Chris@885: Chris@885: Chris@885: