Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/echoes/SecondOrderStyleGenerator.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 101 - (show annotations) (download) (as text)
Fri Feb 1 01:09:56 2013 UTC (11 years, 2 months ago) by haruneko24
File MIME type: text/x-c++src
File size: 5185 byte(s)


1 #include <cmath>
2
3 #include "helper/ControlCommand.h"
4 #include "envelope/Envelope.h"
5 #include "Utility.h"
6 #include "SequenceModel.h"
7 #include "EventItem.h"
8 #include "TrackItem.h"
9 #include "ControlItem.h"
10
11 #include "SecondOrderStyleGenerator.h"
12
13 using namespace stand::echoes;
14
15 SecondOrderStyleGenerator::SecondOrderStyleGenerator()
16 {
17 }
18
19 stand::view::helper::ControlCommand *SecondOrderStyleGenerator::styleCommand(stand::model::SequenceModel *sequence, int trackId, int tickBegin, int tickEnd, int tickResolution, double msFramePeriod)
20 {
21 stand::view::helper::ControlCommand *c = new stand::view::helper::ControlCommand;
22
23 stand::model::TrackItem *track = sequence->track(trackId);
24 stand::model::ControlItem *pitch = track->control(track->data(track->PitchControlId, 0).toInt());
25 stand::model::TreeItem *events = track->events();
26 QVector<QPair<double, double> > notes;
27
28 if(events->childCount() == 0)
29 {
30 return NULL;
31 }
32
33 notes.resize(events->childCount());
34 for(int i = 0; i < events->childCount(); i++)
35 {
36 stand::model::EventItem *item = static_cast<stand::model::EventItem *>(events->child(i));
37 notes[i] = QPair<double, double>(sequence->ms(item->tick()), sequence->ms(item->tick() + item->length()));
38 qDebug("%f, %f", notes[i].first, notes[i].second);
39 }
40
41 double msBegin = sequence->ms(tickBegin);
42 double msEnd = sequence->ms(tickEnd);
43 int size = (msEnd - msBegin) / msFramePeriod + 0.5;
44 double *stepImpulse = new double[size];
45 double *result = new double[size];
46
47 // ������������������������
48 for(int i = 0; i < size; i++)
49 {
50 stepImpulse[i] = result[i] = 0.0;
51 }
52
53 int noteIndex = 0;
54 for(double ms = msBegin; ms < msEnd && noteIndex < notes.size(); ms += msFramePeriod)
55 {
56 // ������������������
57 if(ms < notes[noteIndex].first)
58 {
59 continue;
60 }
61 if(ms > notes[noteIndex].second)
62 {
63 noteIndex++;
64 if(noteIndex == notes.size())
65 {
66 break;
67 }
68 }
69 // ToDo: StepImpulse ������������������
70 int index = (ms - msBegin) / msFramePeriod;
71 index = qMax(0, qMin(size - 1, index));
72 stepImpulse[index] = stand::utility::NoteFrequency(events->child(noteIndex)->data(stand::model::EventItem::NoteData, 0).toInt());
73 }
74 // apply overshoot
75 /* omega = 0.0348;
76 xi = 0.5422;
77 k = 0.0348;
78 _applyH(stepImpulse, result, size, msFramePeriod); // (�������������)���������������������������������
79 */
80 // apply preparation
81 omega = 0.0292;
82 xi = 0.6681;
83 k = 0.0292;
84 _applyH(result, stepImpulse, size, msFramePeriod);
85
86 c->control = pitch;
87 c->oldP = pitch->contour(tickBegin, tickEnd);
88
89 _applyC(c, result, size, sequence, trackId, tickBegin, tickEnd, tickResolution, msFramePeriod);
90
91 delete[] stepImpulse;
92 delete[] result;
93
94 return c;
95 }
96
97 void SecondOrderStyleGenerator::_applyH(double *dst, double *src, int size, double msFramePeriod)
98 {
99 for(int i = 0; i < size; i++)
100 {
101 if(src[i] == 0.0)
102 {
103 continue;
104 }
105 for(int j = 0; j < 1024 && i + j < size; j++)
106 {
107 dst[i + j] += src[i] * h(j * msFramePeriod) * 2;
108 }
109 }
110 }
111
112 double SecondOrderStyleGenerator::h(double sec) const
113 {
114 /* ������������������������������������������������������������������
115 * k
116 * H(s) = ----------------------------
117 * s^2 + 2xi omega s + omega^2
118 *--
119 * case |xi| < 1 && xi != 0:
120 *
121 * omega
122 * h(t) = ------------------- exp(-xi omega t) sin omega (1 - xi^2)^(1 / 2) t)
123 * (1 - xi^2)^(1/2)
124 *--
125 * case |xi| == 1
126 *
127 * h(t) = omega * omega * t * exp(-omega * t);
128 *
129 *--
130 * case |xi| > 1
131 *
132 */
133
134 if(fabs(xi) < 1)
135 {
136 double t1 = sqrt(1 - xi * xi);
137 double t2 = omega / t1 * exp(-xi * omega * sec) * sin(omega * sec * t1);
138 return t2;
139 }
140 else if(fabs(xi) == 1)
141 {
142 return omega * omega * sec * exp(-omega * sec);
143 }
144 else
145 {
146 double t1 = sqrt(1 - xi * xi);
147 double t2 = exp(omega * t1 * sec) - exp(-omega * t1 * sec);
148 double t3 = omega / (2 * t1) * exp(-xi * omega * sec) * t2;
149 return t3;
150 }
151 }
152
153 void SecondOrderStyleGenerator::_applyC(stand::view::helper::ControlCommand *c, double *contour, int size, stand::model::SequenceModel *sequence, int trackId, int tickBegin, int tickEnd, int tickResolution, double msFramePeriod)
154 {
155 double msBegin = sequence->ms(tickBegin);
156 for(int tick = (tickBegin / tickResolution) * tickResolution; tick <= tickEnd; tick += tickResolution)
157 {
158 double ms = sequence->ms(tick) - msBegin;
159 int index = ms / msFramePeriod + 0.5;
160 index = qMax(0, qMin(index, size - 1));
161 double value = contour[index];
162 c->newP.append(stand::utility::ControlPoint(tick, value));
163 }
164 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26