Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/echoes/SecondOrderStyleGenerator.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 101 - (hide 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 haruneko24 101 #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