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);
}
|