Mercurial > hg > wabletios
comparison scanpath.mm @ 0:c667dfe12d47
OK. Ther real deal.
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Mon, 19 Nov 2012 13:00:42 +0000 |
parents | |
children | 1d1bf0aac99e |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c667dfe12d47 |
---|---|
1 /* | |
2 * scanpath.cpp | |
3 * springstructure | |
4 * | |
5 * Created by Robert Tubb on 09/06/2011. | |
6 * Copyright 2011 __MyCompanyName__. All rights reserved. | |
7 * | |
8 */ | |
9 #include <vector> | |
10 #include "scanpath.h" | |
11 #include "testApp.h" | |
12 | |
13 //---------------------------------------------------------------- | |
14 ScanPath::ScanPath() : maxElements(2048) { | |
15 // construct an empty scanpath | |
16 // an ' element ' consists of 1 lump and one spring | |
17 | |
18 | |
19 numElements = 0; // numElements is a dynamic running count of elements when building - a bit crap | |
20 springPath = new Spring*[maxElements]; | |
21 lumpPath = new Lump*[maxElements]; | |
22 | |
23 framesPerSample = ofGetFrameRate()/SAMPLE_RATE; | |
24 frameInterpolator = 0.0; | |
25 currentLength = 0.0; | |
26 restLength = 1.0; // ? | |
27 | |
28 scanMode = DISPLACEMENT; | |
29 | |
30 initWavetables(); | |
31 | |
32 } | |
33 //---------------------------------------------------------------- | |
34 ScanPath::~ScanPath(){ | |
35 delete [] springPath; | |
36 delete [] lumpPath; | |
37 delete [] wavetableNew; | |
38 delete [] wavetableOld; | |
39 delete [] wavetableUpdate; | |
40 cout << "destructed scanpath\n"; | |
41 } | |
42 | |
43 void ScanPath::clear(){ | |
44 for(int i = 0; i<numElements; i++){ | |
45 springPath[i]->removeFromScanPath(); | |
46 lumpPath[i]->removeFromScanPath(); | |
47 } | |
48 numElements = 0; | |
49 // cant work? | |
50 } | |
51 int ScanPath::howManyElements(){ | |
52 return numElements; | |
53 } | |
54 //---------------------------------------------------------------- | |
55 void ScanPath::inscribe(double ax, double ay){ | |
56 // look at coordinates, add the closest lump and it's connecting string | |
57 // if we're further away from current lump | |
58 | |
59 // check end points of connecting springs, pick closest | |
60 } | |
61 void ScanPath::draw(){ | |
62 // draw the actual waveform in the corner | |
63 | |
64 int width = 768; | |
65 int height = 128; | |
66 double sampval = 0.0; | |
67 int leftsampnum = 0; | |
68 int rightsampnum = 0; | |
69 float sampscale = 0.0, prevsampscale = 0.0, interp = 0.0; | |
70 | |
71 ofSetColor(0, 0, 0); | |
72 double step = double(numElements)/width; // how much we are stepping thru wave per pixel | |
73 for(int i = 0; i < width; i++){ | |
74 | |
75 leftsampnum = floor(i * step); // basic nearest neighbour interpolation | |
76 rightsampnum = ceil(i*step); | |
77 interp = (i*step)-leftsampnum; | |
78 if(rightsampnum < numElements){ | |
79 sampval = (1 - interp)*wavetableNew[leftsampnum] + interp*wavetableNew[rightsampnum]; | |
80 } | |
81 sampscale = (sampval * 700) + height/2.0; // centre and scale | |
82 ofSetLineWidth(2); | |
83 ofLine(sampscale, i, prevsampscale, i-1); // draw a line from pixel to pixel (?) | |
84 prevsampscale = sampscale; | |
85 } | |
86 | |
87 } | |
88 void drawCubic(){ | |
89 | |
90 } | |
91 //---------------------------------------------------------------- | |
92 // add spring | |
93 void ScanPath::addSpring(){ | |
94 // see add element | |
95 } | |
96 //---------------------------------------------------------------- | |
97 // add lump | |
98 void ScanPath::addLump(){ | |
99 // see add element | |
100 } | |
101 //---------------------------------------------------------------- | |
102 // add lump | |
103 double ScanPath::getTotalLength(){ | |
104 // for interesting modulations... | |
105 currentLength = 0.0; | |
106 for(int i = 0; i < numElements; i++){ | |
107 currentLength += springPath[i]->getLength(); | |
108 } | |
109 return currentLength; | |
110 | |
111 } | |
112 //---------------------------------------------------------------- | |
113 void ScanPath::initWavetables(){ | |
114 wavetableNew = new double[maxElements]; | |
115 wavetableOld = new double[maxElements]; | |
116 wavetableUpdate = new double[maxElements]; | |
117 | |
118 for(int i = 0; i < maxElements; i++){ | |
119 wavetableOld[i] = 0.0; | |
120 wavetableNew[i] = 0.0; | |
121 wavetableUpdate[i] = 0.0; | |
122 } | |
123 | |
124 } | |
125 //---------------------------------------------------------------- | |
126 void ScanPath::addElement(Lump* aLump, Spring * aSpring){ | |
127 // insert ptr to the lump and spring into array | |
128 if(numElements >= maxElements){ | |
129 cerr << "cannot add any more to scanpath - max elements: 2048\n"; | |
130 return; | |
131 } | |
132 lumpPath[numElements] = aLump; | |
133 springPath[numElements] = aSpring; | |
134 | |
135 aLump->addToScanPath(); | |
136 aSpring->addToScanPath(); | |
137 | |
138 numElements++; | |
139 } | |
140 //---------------------------------------------------------------- | |
141 void ScanPath::updateWavetables(){ | |
142 // swap old , new | |
143 double * temp; | |
144 | |
145 switch(scanMode){ | |
146 case DISPLACEMENT: | |
147 // now fill with new values | |
148 for(int i = 0; i < numElements; i++){ | |
149 | |
150 wavetableUpdate[i] = lumpPath[i]->scanRadialDisplacement()/1.5; | |
151 | |
152 } | |
153 break; | |
154 case SPEED: | |
155 for(int i = 0; i < numElements; i++){ | |
156 wavetableUpdate[i] = lumpPath[i]->scanLumpSpeed(); | |
157 } | |
158 break; | |
159 case SPRING_FORCE: | |
160 for(int i = 0; i < numElements; i++){ | |
161 wavetableUpdate[i] = springPath[i]->getForceMag(); | |
162 } | |
163 break; | |
164 case YPOS: | |
165 for(int i = 0; i < numElements; i++){ | |
166 wavetableUpdate[i] = lumpPath[i]->scanYPos(); | |
167 } | |
168 break; | |
169 default: | |
170 break; | |
171 | |
172 | |
173 } | |
174 | |
175 // reset the interp between frames | |
176 if(audioAccessing){ | |
177 cout << "buffers swapped while update!\n"; | |
178 } | |
179 updateAccessing = true; | |
180 temp = wavetableOld; | |
181 wavetableOld = wavetableNew; | |
182 wavetableNew = wavetableUpdate; | |
183 wavetableUpdate = temp; | |
184 updateAccessing = false; | |
185 | |
186 frameInterpolator = 0.0; | |
187 framesPerSample = 2.0*ofGetFrameRate()/SAMPLE_RATE; // attempt to get a reasonable est. of how fast to interp | |
188 | |
189 } | |
190 //---------------------------------------------------------------- | |
191 // get next sample | |
192 double ScanPath::getNextSample(double aPhasor){ | |
193 // move along path, interpolating between points | |
194 // move between frames too | |
195 double alongPath = aPhasor*double(numElements); | |
196 | |
197 // indexes for interpolated points | |
198 int n0 = floor(alongPath); | |
199 int n1 = n0+1; | |
200 if(n1 >= numElements){ | |
201 n1 = 0; | |
202 } | |
203 | |
204 double frac = alongPath - double(n0); | |
205 | |
206 audioAccessing = true; | |
207 if (updateAccessing){ | |
208 cout << "update is accessing while audio is\n"; | |
209 } | |
210 double oldsample = (1 - frac) * wavetableOld[n0] + frac * wavetableOld[n1]; | |
211 | |
212 double newsample = (1 - frac) * wavetableNew[n0] + frac * wavetableNew[n1]; | |
213 | |
214 audioAccessing = false; | |
215 | |
216 frameInterpolator += framesPerSample; | |
217 if(frameInterpolator >= 1.0){ | |
218 //cout << "frame interp > 1\n"; | |
219 frameInterpolator = 1.0; // just stays outputting new | |
220 } | |
221 | |
222 double sample = (1 - frameInterpolator)*oldsample + frameInterpolator*newsample; | |
223 //cout << sample << endl; | |
224 // keep within the bounds of acceptability | |
225 if(sample > 0.99){ | |
226 // cout << "OUCH\n"; | |
227 sample = 0.99; | |
228 }else if(sample < -0.99){ | |
229 sample = -0.99; | |
230 } | |
231 return sample; | |
232 | |
233 } | |
234 //---------------------------------------------------------------- | |
235 // get next sample | |
236 double ScanPath::getNextSample(){ | |
237 // move along wavetable, no interpolation ie: length of path is pitch | |
238 static int n = 0; | |
239 double oldsample = wavetableOld[n]; | |
240 | |
241 double newsample = wavetableNew[n]; | |
242 n++; | |
243 if (n >= numElements){ | |
244 n = 0; | |
245 } | |
246 | |
247 frameInterpolator += framesPerSample; | |
248 if(frameInterpolator >= 1.0){ | |
249 //cout << "frame interp > 1\n"; | |
250 frameInterpolator = 1.0; // just stays outputting new | |
251 } | |
252 | |
253 double sample = (1 - frameInterpolator)*oldsample + frameInterpolator*newsample; | |
254 return sample*3.0; | |
255 | |
256 } | |
257 //---------------------------------------------------------------- | |
258 //---------------------------------------------------------------- | |
259 // get next sample with cubic interpolation | |
260 double ScanPath::getNextSampleCubic(double aPhasor){ | |
261 // move along path, interpolating between points | |
262 // move between frames too | |
263 double alongPath = aPhasor*double(numElements); | |
264 | |
265 // indexes for interpolated points | |
266 int n1 = floor(alongPath); | |
267 | |
268 int n0 = n1-1; | |
269 if(n0 < 0){ | |
270 n0 = numElements; | |
271 } | |
272 int n2 = n1+1; | |
273 if(n2 >= numElements){ | |
274 n2 = 0; | |
275 } | |
276 int n3 = n2+1; | |
277 if(n3 >= numElements){ | |
278 n3 = 0; | |
279 } | |
280 double frac = alongPath - double(n0); | |
281 double fracSquared = frac * frac; | |
282 double fracCubed = fracSquared * frac; | |
283 double a0,a1,a2,a3; | |
284 //cout << n0 << endl; | |
285 // cubic interp | |
286 /* | |
287 double y0,double y1, | |
288 double y2,double y3, | |
289 double mu) | |
290 { | |
291 double a0,a1,a2,a3,mu2; | |
292 | |
293 mu2 = mu*mu; | |
294 a0 = y3 - y2 - y0 + y1; | |
295 a1 = y0 - y1 - a0; | |
296 a2 = y2 - y0; | |
297 a3 = y1; | |
298 | |
299 return(a0*mu*mu2+a1*mu2+a2*mu+a3); | |
300 */ | |
301 a0 = wavetableOld[n3] - wavetableOld[n2] - wavetableOld[n0] + wavetableOld[n1]; | |
302 a1 = wavetableOld[n0] - wavetableOld[n1] - a0; // y0 - y1 - a0; | |
303 a2 = wavetableOld[n2] - wavetableOld[n0]; // y2 - y0; | |
304 a3 = wavetableOld[n1]; | |
305 | |
306 double oldsample = a0*fracCubed + a1*fracSquared + a2*frac + a3; | |
307 | |
308 a0 = wavetableNew[n3] - wavetableNew[n2] - wavetableNew[n0] + wavetableNew[n1]; | |
309 a1 = wavetableNew[n0] - wavetableNew[n1] - a0; // y0 - y1 - a0; | |
310 a2 = wavetableNew[n2] - wavetableNew[n0]; // y2 - y0; | |
311 a3 = wavetableNew[n1]; | |
312 | |
313 double newsample = a0*fracCubed + a1*fracSquared + a2*frac + a3; | |
314 | |
315 frameInterpolator += framesPerSample; | |
316 if(frameInterpolator >= 1.0){ | |
317 frameInterpolator = 1.0; // just stays outputting new | |
318 } | |
319 | |
320 double sample = (1 - frameInterpolator)*oldsample + frameInterpolator*newsample; | |
321 //cout << sample << endl; | |
322 // keep within the bounds of acceptability | |
323 | |
324 // beef up | |
325 sample = sample*3.0; | |
326 | |
327 if(sample > 0.99){ | |
328 sample = 0.99; | |
329 }else if(sample < -0.99){ | |
330 sample = -0.99; | |
331 } | |
332 | |
333 return sample; | |
334 | |
335 } | |
336 //---------------------------------------------------------------- |