/[qspeakers]/branches/qtcharts/optimizer.cpp
ViewVC logotype

Contents of /branches/qtcharts/optimizer.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 282 - (show annotations)
Tue Oct 27 14:39:18 2020 UTC (7 months, 2 weeks ago) by ben
File size: 5278 byte(s)
Fix typo
1 #include <math.h>
2
3 #include "optimizer.h"
4 #include "mainwindow.h"
5 #include "undocommands.h"
6
7 Optimizer::Optimizer(const Speaker& speaker, SealedBox *box, int sibling, QObject* parent) :
8 speaker(speaker),
9 box(box),
10 type(BOX_SEALED),
11 sibling(sibling),
12 mainwindow(static_cast<MainWindow*>(parent))
13 {
14 }
15
16 Optimizer::Optimizer(const Speaker &speaker, PortedBox *box, int sibling, QObject *parent) :
17 speaker(speaker),
18 box(box),
19 type(BOX_PORTED),
20 sibling(sibling),
21 mainwindow(static_cast<MainWindow*>(parent))
22 {
23 }
24
25 Optimizer::Optimizer(const Speaker &speaker, BandPassBox *box, int sibling, QObject *parent) :
26 speaker(speaker),
27 box(box),
28 type(BOX_BANDPASS),
29 sibling(sibling),
30 mainwindow(static_cast<MainWindow*>(parent))
31 {
32 }
33
34 void Optimizer::genericOptimizeBox()
35 {
36 if (type == BOX_SEALED) {
37 SealedBox *b = (SealedBox *)box;
38
39 double qr = 0.707 / speaker.getQts();
40 double vr = pow(qr, 2.0) - 1;
41
42 if (nullptr == mainwindow) {
43 b->setVolume(speaker.getVas() * sibling / vr);
44 } else {
45 SealedVolumeCommand* com = new SealedVolumeCommand(b->getVolume(), speaker.getVas() * sibling / vr, mainwindow);
46 mainwindow->getCommandStack()->beginMacro(QObject::tr("optimizing sealed box"));
47 mainwindow->getCommandStack()->push(com);
48 mainwindow->getCommandStack()->endMacro();
49 }
50 } else if (type == BOX_PORTED) {
51 /* approx. "natural max flat", a good starting point */
52 double vb = (20 * speaker.getVas() * sibling * pow(speaker.getQts(), 3.3));
53 double fb = speaker.getFs() * pow(speaker.getVas() * sibling / vb, 0.31);
54 portedAlignVb_Fb(vb, fb, QObject::tr("applying 'max flat' alignment"));
55 } else {
56 /* default optimization for 0dB ripple (s) and 0dB gain (pa)*/
57 double s = 0.7;
58 double pa = 0.0;
59 bandpassAlignS_Pa(s, pa);
60 }
61 }
62
63 void Optimizer::portedAlignBessel()
64 {
65 double vb = 8.0707 * pow(speaker.getQts(), 2.5848) * speaker.getVas() * sibling;
66 double fb = 0.3552 * pow(speaker.getQts(), -0.9649) * speaker.getFs();
67 portedAlignVb_Fb(vb, fb, QObject::tr("applying Bessel alignment"));
68 }
69
70 void Optimizer::portedAlignBullock()
71 {
72 double qts = speaker.getQts();
73 double vb = qts * speaker.getVas() * sibling * (4.96 * qts - 0.136);
74 double fb = speaker.getFs();
75 portedAlignVb_Fb(vb, fb, QObject::tr("applying Bullock alignment"));
76 }
77
78 void Optimizer::portedAlignKeele_Hoge()
79 {
80 double vb = speaker.getVas() * sibling * 5.2358 * pow(speaker.getQts(), 2.1687);
81 double fb = speaker.getFs();
82 portedAlignVb_Fb(vb, fb, QObject::tr("applying Keele & Hoge alignment"));
83 }
84
85 void Optimizer::portedAlignLegendre()
86 {
87 double vb = 10.728 * pow(speaker.getQts(), 2.4186) * speaker.getVas() * sibling;
88 double fb = 0.3802 * pow(speaker.getQts(), -1.0657) * speaker.getFs();
89 portedAlignVb_Fb(vb, fb, QObject::tr("applying Legendre alignment"));
90 }
91
92 void Optimizer::portedAlignModerate_Inf()
93 {
94 /* use M4 Moderate alignment (see http://www.mzbinden.ch/ventedalignments/index.html) */
95 double vb = (2.52 * speaker.getQts() - 0.35) * speaker.getVas() * sibling;
96 double fb = 0.32 * sqrt((1.0/pow(speaker.getQts(), 2.0)) + 3.38) * speaker.getFs();
97 portedAlignVb_Fb(vb, fb, QObject::tr("applying Zbinden alignment"));
98 }
99
100 void Optimizer::portedAlignVb_Fb(double vb, double fb, const QString& title)
101 {
102 PortedBox *b = (PortedBox *)box;
103 if (nullptr == mainwindow) {
104 b->setBoxVolume(vb);
105 b->setResFreq(fb);
106 b->updatePorts(speaker.getSd() * sibling, speaker.getXmax());
107 } else {
108 QUndoStack* stack = mainwindow->getCommandStack();
109 stack->beginMacro(title);
110 PortedVolumeCommand* com1 = new PortedVolumeCommand(b->getBoxVolume(), vb, mainwindow);
111 stack->push(com1);
112 PortedResFreqCommand* com2 = new PortedResFreqCommand(b->getResFreq(), fb, mainwindow);
113 stack->push(com2);
114 stack->endMacro();
115 }
116 }
117
118 void Optimizer::bandpassAlignS_Pa(double s, double pa)
119 {
120 BandPassBox *b = (BandPassBox *)box;
121 /* see http://www.diysubwoofers.org/bnd/4thord1.htm */
122 double qbp = pow((pow(10.0,(-pa/40.0)) * 2 * s ), -1);
123 double fb = qbp * speaker.getFs() / speaker.getQts();
124 double vf = pow(2 * s * speaker.getQts(), 2) * speaker.getVas() * sibling;
125 double vr = speaker.getVas() * sibling / (pow(qbp / speaker.getQts(), 2) - 1);
126 if (nullptr == mainwindow) {
127 b->setSealedBoxVolume(vr);
128 b->setPortedBoxVolume(vf);
129 b->setPortedBoxResFreq(fb);
130 b->updatePortedBoxPorts(speaker.getSd() * sibling, speaker.getXmax());
131 } else {
132 QUndoStack* stack = mainwindow->getCommandStack();
133 stack->beginMacro(QObject::tr("applying bandpass box alignment"));
134 BPSealedVolumeCommand* com1 = new BPSealedVolumeCommand(b->getSealedBoxVolume(), vr, mainwindow);
135 stack->push(com1);
136 BPPortedVolumeCommand* com2 = new BPPortedVolumeCommand(b->getPortedBoxVolume(), vf, mainwindow);
137 stack->push(com2);
138 BPPortedResFreqCommand* com3 = new BPPortedResFreqCommand(b->getPortedBoxResFreq(), fb, mainwindow);
139 stack->push(com3);
140 stack->endMacro();
141 }
142 }

  ViewVC Help
Powered by ViewVC 1.1.26