diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scanpath.mm	Mon Nov 19 13:00:42 2012 +0000
@@ -0,0 +1,336 @@
+/*
+ *  scanpath.cpp
+ *  springstructure
+ *
+ *  Created by Robert Tubb on 09/06/2011.
+ *  Copyright 2011 __MyCompanyName__. All rights reserved.
+ *
+ */
+#include <vector>
+#include "scanpath.h"
+#include "testApp.h"
+
+//----------------------------------------------------------------
+ScanPath::ScanPath() : maxElements(2048) {
+	// construct an empty scanpath
+	// an ' element ' consists of 1 lump and one spring
+
+    
+	numElements = 0; // numElements is a dynamic running count of elements when building - a bit crap
+    springPath = new Spring*[maxElements];
+    lumpPath = new Lump*[maxElements];
+    
+    framesPerSample = ofGetFrameRate()/SAMPLE_RATE;
+    frameInterpolator = 0.0;
+    currentLength = 0.0;
+    restLength = 1.0; // ?
+
+    scanMode = DISPLACEMENT;
+    
+    initWavetables();
+
+}
+//----------------------------------------------------------------
+ScanPath::~ScanPath(){
+	delete [] springPath;
+    delete [] lumpPath;
+    delete [] wavetableNew;
+    delete [] wavetableOld;
+    delete [] wavetableUpdate;
+    cout << "destructed scanpath\n"; 
+}
+
+void ScanPath::clear(){
+    for(int i = 0; i<numElements; i++){
+        springPath[i]->removeFromScanPath();
+        lumpPath[i]->removeFromScanPath();
+    }
+    numElements = 0;
+    // cant work?
+}
+int ScanPath::howManyElements(){
+    return numElements;
+}
+//----------------------------------------------------------------
+void ScanPath::inscribe(double ax, double ay){
+	// look at coordinates, add the closest lump and it's connecting string 
+	// if we're further away from current lump
+	
+	// check end points of connecting springs, pick closest
+}
+void ScanPath::draw(){
+    // draw the actual waveform in the corner
+
+    int width = 768;
+    int height = 128;
+    double sampval = 0.0;
+    int leftsampnum = 0;
+    int rightsampnum = 0;
+    float sampscale = 0.0, prevsampscale = 0.0, interp = 0.0;
+
+     ofSetColor(0, 0, 0);
+    double step = double(numElements)/width; // how much we are stepping thru wave per pixel
+    for(int i = 0; i < width; i++){
+        
+        leftsampnum = floor(i * step); // basic nearest neighbour interpolation
+        rightsampnum = ceil(i*step);
+        interp  = (i*step)-leftsampnum;
+        if(rightsampnum < numElements){
+            sampval = (1 - interp)*wavetableNew[leftsampnum] + interp*wavetableNew[rightsampnum];
+        }
+        sampscale = (sampval * 700) + height/2.0; // centre and scale
+        ofSetLineWidth(2);
+        ofLine(sampscale, i, prevsampscale, i-1); // draw a line from pixel to pixel (?)
+        prevsampscale = sampscale;
+    }
+    
+}
+void drawCubic(){
+    
+}
+//----------------------------------------------------------------
+// add spring
+void ScanPath::addSpring(){
+	// see add element
+}
+//----------------------------------------------------------------
+// add lump
+void ScanPath::addLump(){
+    // see add element
+}
+//----------------------------------------------------------------
+// add lump
+double ScanPath::getTotalLength(){
+    // for interesting modulations...
+    currentLength = 0.0;
+    for(int i = 0; i < numElements; i++){
+        currentLength += springPath[i]->getLength();
+    }
+    return currentLength;
+    
+}
+//----------------------------------------------------------------
+void ScanPath::initWavetables(){
+    wavetableNew = new double[maxElements];
+    wavetableOld = new double[maxElements];
+    wavetableUpdate = new double[maxElements];
+    
+    for(int i = 0; i < maxElements; i++){
+        wavetableOld[i] = 0.0;
+        wavetableNew[i] = 0.0;
+        wavetableUpdate[i] = 0.0;
+    }
+    
+}
+//----------------------------------------------------------------
+void ScanPath::addElement(Lump* aLump, Spring * aSpring){
+    // insert ptr to the lump and spring into array
+    if(numElements >= maxElements){
+        cerr << "cannot add any more to scanpath - max elements: 2048\n";
+        return;
+    }
+    lumpPath[numElements] = aLump;
+    springPath[numElements] = aSpring;
+    
+    aLump->addToScanPath();
+    aSpring->addToScanPath();
+    
+    numElements++;
+}
+//----------------------------------------------------------------
+void ScanPath::updateWavetables(){
+    // swap old , new
+    double * temp;
+
+    switch(scanMode){
+        case DISPLACEMENT:
+            // now fill with new values
+            for(int i = 0; i < numElements; i++){
+
+                wavetableUpdate[i] = lumpPath[i]->scanRadialDisplacement()/1.5;
+                
+            }
+            break;
+        case SPEED:
+            for(int i = 0; i < numElements; i++){
+                wavetableUpdate[i] = lumpPath[i]->scanLumpSpeed();
+            }
+            break;
+        case SPRING_FORCE:
+            for(int i = 0; i < numElements; i++){
+                wavetableUpdate[i] = springPath[i]->getForceMag();
+            }
+            break;
+        case YPOS:
+            for(int i = 0; i < numElements; i++){
+                wavetableUpdate[i] = lumpPath[i]->scanYPos();
+            }
+            break;
+        default:
+            break;
+            
+          
+    }
+ 
+    // reset the interp between frames
+    if(audioAccessing){
+        cout << "buffers swapped while update!\n";
+    }
+    updateAccessing = true;   
+    temp = wavetableOld;
+    wavetableOld = wavetableNew;
+    wavetableNew = wavetableUpdate;
+    wavetableUpdate = temp;
+    updateAccessing = false;
+    
+    frameInterpolator = 0.0;
+    framesPerSample = 2.0*ofGetFrameRate()/SAMPLE_RATE; // attempt to get a reasonable est. of how fast to interp
+    
+}
+//----------------------------------------------------------------
+// get next sample
+double ScanPath::getNextSample(double aPhasor){
+	// move along path, interpolating between points
+    // move between frames too
+    double alongPath = aPhasor*double(numElements);
+    
+    // indexes for interpolated points
+    int n0 = floor(alongPath);
+    int n1 = n0+1;
+    if(n1 >= numElements){
+        n1 = 0;
+    }
+
+    double frac = alongPath - double(n0);
+    
+    audioAccessing = true;
+    if (updateAccessing){
+        cout << "update is accessing while audio is\n";
+    }
+    double oldsample = (1 - frac) * wavetableOld[n0] + frac * wavetableOld[n1];
+    
+    double newsample = (1 - frac) * wavetableNew[n0] + frac * wavetableNew[n1];
+    
+    audioAccessing = false;
+    
+    frameInterpolator += framesPerSample;
+    if(frameInterpolator >= 1.0){
+        //cout << "frame interp > 1\n";
+        frameInterpolator = 1.0; // just stays outputting new
+    }
+    
+    double sample = (1 - frameInterpolator)*oldsample + frameInterpolator*newsample;
+    //cout << sample << endl;
+    // keep within the bounds of acceptability
+    if(sample > 0.99){
+       // cout << "OUCH\n";
+        sample = 0.99;
+    }else if(sample < -0.99){
+        sample = -0.99;
+    }
+    return sample;
+	
+}
+//----------------------------------------------------------------
+// get next sample
+double ScanPath::getNextSample(){
+	// move along wavetable, no interpolation ie: length of path is pitch
+    static int n = 0;
+    double oldsample = wavetableOld[n];
+    
+    double newsample = wavetableNew[n]; 
+    n++;
+    if (n >= numElements){
+        n = 0;
+    }
+
+    frameInterpolator += framesPerSample;
+    if(frameInterpolator >= 1.0){
+        //cout << "frame interp > 1\n";
+        frameInterpolator = 1.0; // just stays outputting new
+    }
+    
+    double sample = (1 - frameInterpolator)*oldsample + frameInterpolator*newsample;
+    return sample*3.0;
+	
+}
+//----------------------------------------------------------------
+//----------------------------------------------------------------
+// get next sample with cubic interpolation
+double ScanPath::getNextSampleCubic(double aPhasor){
+	// move along path, interpolating between points
+    // move between frames too
+    double alongPath = aPhasor*double(numElements);
+    
+    // indexes for interpolated points
+    int n1 = floor(alongPath);
+    
+    int n0 = n1-1;
+    if(n0 < 0){
+        n0 = numElements;
+    }
+    int n2 = n1+1;
+    if(n2 >= numElements){
+        n2 = 0;
+    }
+    int n3 = n2+1;
+    if(n3 >= numElements){
+        n3 = 0;
+    }
+    double frac = alongPath - double(n0);
+    double fracSquared = frac * frac;
+    double fracCubed = fracSquared * frac;
+    double a0,a1,a2,a3;
+    //cout << n0 << endl;
+    // cubic interp
+    /*
+     double y0,double y1,
+     double y2,double y3,
+     double mu)
+     {
+     double a0,a1,a2,a3,mu2;
+     
+     mu2 = mu*mu;
+     a0 = y3 - y2 - y0 + y1;
+     a1 = y0 - y1 - a0;
+     a2 = y2 - y0;
+     a3 = y1;
+     
+     return(a0*mu*mu2+a1*mu2+a2*mu+a3);
+     */
+    a0 = wavetableOld[n3] - wavetableOld[n2] - wavetableOld[n0] + wavetableOld[n1];
+    a1 = wavetableOld[n0] - wavetableOld[n1] - a0; //  y0 - y1 - a0;
+    a2 = wavetableOld[n2] - wavetableOld[n0]; // y2 - y0;
+    a3 = wavetableOld[n1];
+    
+    double oldsample = a0*fracCubed + a1*fracSquared + a2*frac + a3;
+    
+    a0 = wavetableNew[n3] - wavetableNew[n2] - wavetableNew[n0] + wavetableNew[n1];
+    a1 = wavetableNew[n0] - wavetableNew[n1] - a0; //  y0 - y1 - a0;
+    a2 = wavetableNew[n2] - wavetableNew[n0]; // y2 - y0;
+    a3 = wavetableNew[n1];
+    
+    double newsample = a0*fracCubed + a1*fracSquared + a2*frac + a3;
+    
+    frameInterpolator += framesPerSample;
+    if(frameInterpolator >= 1.0){
+        frameInterpolator = 1.0; // just stays outputting new
+    }
+    
+    double sample = (1 - frameInterpolator)*oldsample + frameInterpolator*newsample;
+    //cout << sample << endl;
+    // keep within the bounds of acceptability
+    
+    // beef up
+    sample = sample*3.0;
+    
+    if(sample > 0.99){
+        sample = 0.99;
+    }else if(sample < -0.99){
+        sample = -0.99;
+    }
+    
+    return sample;
+	
+}
+//----------------------------------------------------------------
\ No newline at end of file