File: system.cpp

package info (click to toggle)
qspeakers 1.8.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 900 kB
  • sloc: cpp: 4,593; xml: 708; sh: 13; makefile: 2
file content (104 lines) | stat: -rw-r--r-- 4,348 bytes parent folder | download
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
#include <QDebug>
#include <QObject>

#include <cmath>

#include "system.h"

#define QLVented 7       /* common ported box resonance quality loss (now unused) */
#define QLBandpass 10000 /* common bandpass box quality loss (now unused) */

System::System(const Speaker& s, const SealedBox *b, unsigned int number) :
    speaker(s),
    box(b),
    type(BOX_SEALED),
    sibling(number)
{
}

System::System(const Speaker& s, const PortedBox *b, unsigned int number) :
    speaker(s),
    box(b),
    type(BOX_PORTED),
    sibling(number)
{
}

System::System(const Speaker& s, const BandPassBox *b, unsigned int number) :
    speaker(s),
    box(b),
    type(BOX_BANDPASS),
    sibling(number)
{
}

double System::response(double f)
{
    if (type == BOX_SEALED) {
        SealedBox *b = (SealedBox *)box;
        double vr = speaker.getVas() * sibling / b->getVolume();
        double qr = sqrt(vr + 1.0);
        double qtc = qr * speaker.getQts();
        double fb = qr * speaker.getFs();
        double fr = pow(f / fb, 2.0);
        double db = 10 * log10(pow(fr, 2.0) / (pow(fr - 1, 2.0) + fr/pow(qtc, 2.0)));
        return db;
    } else if (type == BOX_PORTED) {
        PortedBox *b = (PortedBox *)box;
        double A = pow(b->getResFreq() / speaker.getFs(), 2.0);
        double B = A / speaker.getQts() + b->getResFreq() / (b->getLossQualityFactor() * speaker.getFs() * speaker.getQts());
        double C = 1.0 + A + (speaker.getVas() * sibling / b->getBoxVolume()) + b->getResFreq() / (b->getLossQualityFactor() * speaker.getFs() * speaker.getQts());
        double D = 1.0 / speaker.getQts() + b->getResFreq() / (b->getLossQualityFactor() * speaker.getFs());
        double fn2 = pow(f / speaker.getFs(), 2.0);
        double fn4 = pow(fn2, 2.0);
        double db = 10 * log10(pow(fn4, 2.0) / (pow(fn4 - C * fn2 + A, 2.0) + fn2 * pow(D * fn2 - B, 2.0)));
        return db;
    } else {
        BandPassBox *b = (BandPassBox *)box;
        double A = pow(1.0 / (b->getPortedBoxResFreq()), 2.0) * pow(f, 4.0);
        double B = ((1 / b->getLossQualityFactor() + (speaker.getFs() / b->getPortedBoxResFreq()) / speaker.getQts()) / b->getPortedBoxResFreq()) * pow(f, 3.0);
        double C = (((1 + speaker.getVas() * sibling / b->getSealedBoxVolume() + speaker.getVas() * sibling / b->getPortedBoxVolume()) *
                     speaker.getFs() / b->getPortedBoxResFreq() + (1 / speaker.getQts()) / b->getLossQualityFactor()) * speaker.getFs() / b->getPortedBoxResFreq() + 1) * pow(f, 2.0);
        double D = ((1 / speaker.getQts() + (speaker.getFs() / b->getPortedBoxResFreq()) / b->getLossQualityFactor() * (speaker.getVas() * sibling / b->getSealedBoxVolume() + 1)) *
                    speaker.getFs()) * f;
        double E = (speaker.getVas() * sibling / b->getSealedBoxVolume() + 1) * pow(speaker.getFs(), 2);
        double G = A - C + E;
        double H = -B + D;
        double db = 20 * log10(pow(f, 2.0) / sqrt(pow(G, 2.0) + pow(H, 2.0)));
        return db;
    }
}

void System::render(QPainter *painter, const QRectF& area)
{
    QFont orig = painter->font();

    qreal textHeight = painter->fontMetrics().height();
    QTextOption option(Qt::AlignLeft);
    QRectF elementArea(area);
    const int elements = 2;

    QFont font;
    font.setBold(true);
    painter->setFont(font);

    elementArea.moveTop(elementArea.y() + textHeight); /* start after first line */
    elementArea.setHeight((area.height() - textHeight) / elements);
    elementArea.setHeight(elementArea.height() - 2 * textHeight); /* each element has 2 header lines */

    /* elements */
    elementArea.moveTop(elementArea.y() + textHeight); /* blank line */
    painter->drawText(elementArea, QObject::tr("Loudspeaker(s): ") + QString::number(sibling), option);
    elementArea.moveTop(elementArea.y() + textHeight);
    speaker.render(painter, elementArea);

    elementArea.moveTop(elementArea.y() + elementArea.height());

    elementArea.moveTop(elementArea.y() + textHeight); /* blank line */
    QString boxstr = type == BOX_SEALED ? QObject::tr("sealed") : type == BOX_PORTED ? QObject::tr("ported") : QObject::tr("bandpass");
    painter->drawText(elementArea, QObject::tr("Enclosure: ") + boxstr, option);
    elementArea.moveTop(elementArea.y() + textHeight);
    box->render(painter, elementArea);

    painter->setFont(orig);
}