File: createguidedialog.cpp

package info (click to toggle)
tiatracker 1.3-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,664 kB
  • sloc: cpp: 8,875; asm: 664; makefile: 8
file content (135 lines) | stat: -rw-r--r-- 4,825 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "createguidedialog.h"
#include "ui_createguidedialog.h"

#include <QMap>
#include <QString>
#include "tiasound/tiasound.h"
#include "tiasound/pitchguidefactory.h"
#include "percussiontab.h"
#include <iostream>
#include "mainwindow.h"
#include <QProgressDialog>
#include "guidekeyboard.h"
#include <QKeyEvent>
#include <cmath>


CreateGuideDialog::CreateGuideDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CreateGuideDialog)
{
    ui->setupUi(this);
    // Fill waveform selector
    for (int i = 0; i < checkBoxNames.keys().size(); ++i) {
        TiaSound::Distortion dist = checkBoxNames.keys()[i];
        ui->comboBoxGuideWaveforms->addItem(TiaSound::getDistortionName(dist));
    }
}

CreateGuideDialog::~CreateGuideDialog()
{
    delete ui;
}

/*************************************************************************/

void CreateGuideDialog::keyPressEvent(QKeyEvent *e) {
    switch (e->key()) {
    case Qt::Key_Return:
    case Qt::Key_Enter:
        break;

    default:
        QDialog::keyPressEvent (e);
    }
}

/*************************************************************************/

void CreateGuideDialog::on_pushButtonCreateGuide_clicked() {
    int threshold = ui->spinBoxGuideMaxOffTune->value();
    QString name = ui->lineEditGuideName->text();
    TiaSound::TvStandard standard = ui->radioButtonGuidePal->isChecked() ? TiaSound::TvStandard::PAL : TiaSound::TvStandard::NTSC;
    TiaSound::PitchGuideFactory pg;

    // Optimize
    long bestError = 99999999;
    double bestFreq = 0;
    int bestNum = 0;
    int maxNoteDeviation = ui->spinBoxGuideMaxDeviation->value();
    double lowerBound = std::pow(2.0, -maxNoteDeviation/12.0) * 440.0;
    double upperBound = std::pow(2.0, maxNoteDeviation/12.0) * 440.0;

    // Loop over frequencies in range
    QProgressDialog pd("Optimizing pitch guide...", "Cancel", 0, (upperBound - lowerBound)*10, this);
    pd.setWindowModality(Qt::WindowModal);
    pd.setMinimumDuration(0);
    GuideKeyboard *keyboard = findChild<GuideKeyboard *>("guidePianoKeyboard");

    for (double f = lowerBound; f < upperBound; f += 0.1) {
        pd.setValue((f - lowerBound)*10);
        long currentError = 0;
        int curNum = 0;
        // For this frequency, loop over all requested distortions
        for (int i = 0; i < checkBoxNames.size(); ++i) {
            TiaSound::Distortion dist = checkBoxNames.keys()[i];
            QCheckBox *cbDist = findChild<QCheckBox *>(checkBoxNames[dist]);
            if (cbDist->isChecked()) {
                QList<TiaSound::FrequencyPitchGuide> guide = pg.calcInstrumentPitchGuide(standard, dist, f);
                for (int i = 0; i < guide.size(); ++i) {
                    // Consider only requested notes
                    if (guide[i].note != TiaSound::Note::NotANote) {
                        int noteIndex = TiaSound::getIntFromNote(guide[i].note);
                        if (keyboard->keyInfo[noteIndex].isEnabled
                                && std::abs(guide[i].percentOff) <= threshold) {
                            currentError += guide[i].percentOff*guide[i].percentOff;
                            curNum++;
                        }
                    }
                }
            }
        }
        // Now check if new best has been found
        if (curNum > bestNum || (curNum == bestNum && currentError < bestError)) {
            bestError = currentError;
            bestFreq = f;
            bestNum = curNum;
        }
        // Cancel pressed?
        if (pd.wasCanceled()) {
            ui->labelGuideBaseFreq->setText("");
            isGuideCreated = false;
            ui->guidePianoKeyboard->removeGuide();
            update();
            return;
        }
    }

    // Now create pitch guide for the best frequency
    newGuide = pg.calculateGuide(name, standard, bestFreq);
    isGuideCreated = true;

    // Set A4= label text
    ui->labelGuideBaseFreq->setText("A4 = " + QString::number(newGuide.baseFreq) + "Hz.");
    on_comboBoxGuideWaveforms_currentIndexChanged(ui->comboBoxGuideWaveforms->currentIndex());
}

/*************************************************************************/

void CreateGuideDialog::on_comboBoxGuideWaveforms_currentIndexChanged(int index) {
    if (isGuideCreated) {
        TiaSound::Distortion dist = checkBoxNames.keys()[index];
        TiaSound::InstrumentPitchGuide *guide = &(newGuide.instrumentGuides[dist]);
        int threshold = ui->spinBoxGuideMaxOffTune->value();
        ui->guidePianoKeyboard->setInstrumentPitchGuide(guide, threshold);
        update();
    }
}

/*************************************************************************/

void CreateGuideDialog::on_lineEditGuideName_editingFinished() {
    if (isGuideCreated) {
        newGuide.name = ui->lineEditGuideName->text();
    }
}