Offset when reading a sample

Hello,

I would like to resample a first sample of datas that following a circular movement. Moreover movement of first and second sample are made with interpolations.

You make movement with mouseY, you trig the recording by pressing mouse. You have the first sample.
To record the first sample, press R once. You press Z to cancel the resampling and press R to record again.

The problem is, when I record the first sample, the second sample is played with an offset.
But sometimes, it works!

I can’t understand for what reason? Maybe the way of trigging the second sample but i’m not sure.

I put the program below with Class. How can I give the program in attachment?

// TRIGGING SAMPLE
int doubleMeasure,lastSec;
int measure=0;

// to interpolate angle
float mlerp(float x0, float x1, float t, float M ){
   float dx = (x1 - x0 + 1.5*M) % M - 0.5*M;
   return (x0 + t * dx + M) % M;
}
// to manage the begining, the end or recording.
boolean bRecording = false;
boolean mouseRecorded;
float currTime;
float nextSamplePeriod = 2.0;
// to manage the overSampling
float xSampler, ySampler;
float xSamplerOverRec, ySamplerOverRec;
float xAngle, yAngle;
float dataToResample, angleOverRec;

class Sample {
  float t, x, y;
  Sample( float t, float x, float y ) {
    this.t = t;  this.x = x;  this.y = y;
  }
}
boolean bRecordingOverRec = false;
boolean mouseRecordedOverRec;

class SampleOverRec {
  float t, x, y;
  SampleOverRec( float t, float x, float y ) {
    this.t = t;  this.x = x;  this.y = y;
  }
}

Sampler sampler;
ArrayList<Sampler> samplers;

SamplerOverRec samplerOverRec;
ArrayList<SamplerOverRec> samplersOverRec;

void setup() {
  size( 800, 800, P3D );
  frameRate( 30 );
  samplers = new ArrayList<Sampler>();
  samplersOverRec = new ArrayList<SamplerOverRec>();
}

void draw() {
      print( " INTERNAL CLOCK LastSec " )  ; print( " doubleMeasure " ) ; print( doubleMeasure ) ; print( " measure ") ;println( measure ) ;
     if  (doubleMeasure!=lastSec){
          lastSec=doubleMeasure;
          measure ++;
     }
    doubleMeasure = second()%3;  // Values from 0 - 2
    float angle = map (mouseY, 0, 400, 0,  TWO_PI)*1;
  
    // active and draw the first sample
    activeSamplingEachTwoSecond();
    samplingMovement();
    noStroke();
    fill( 60, 60, 127 );
    circle ( 100* cos (yAngle)+300, 100*sin (yAngle)+400, 20);
    print (" sample ");  print (ySampler); print (" ySamplerOverRec "); println (ySamplerOverRec);  
    
    // active and draw the second sample overRecoding the first
    activeSamplingSecondOverRec();
    samplingMovementOverRec();
    noStroke();
    fill( 255, 40, 80 );
    circle ( 100* cos (angleOverRec)+500, 100*sin (angleOverRec)+400, 20);
    
    // circle to show what is recorded 
    noStroke();
    fill( 127, 40, 40 );
    circle ( 100* cos (angle)+100, 100*sin (angle)+400, 20);     
  }
 
void samplingMovement() {  
  currTime = millis() * 0.001;  // seconds since app started
  background( 0 );
  for( int i=0; i<3; i++ ) {
    float p = pow( 2, i );
    stroke( 64, p == nextSamplePeriod ? 255 : 64, 64 );
    rect( (currTime % p) / p * width, i*10, 2, 8 );
  }
  if( bRecording ) {
    samplers.get(samplers.size()-1).addSample( currTime, mouseX, mouseY );  
  }  
  for( Sampler s : samplers )
    s.draw( currTime );
}

void samplingMovementOverRec() {  
  //USELESS***
  /*
   currTime = millis() * 0.001;  // seconds since app started
  for( int i=0; i<3; i++ ) {
    float p = pow( 2, i );
    stroke( 64, p == nextSamplePeriod ? 255 : 64, 64 );
    rect( (currTime % p) / p * width, i*10, 2, 8 );
  }
  */
 //END OF USELESS***
  if( bRecordingOverRec ) {
    samplersOverRec.get(samplersOverRec.size()-1).addSample( currTime, xSampler, ySampler );  
  }  
  for( SamplerOverRec s : samplersOverRec )
    s.draw( currTime );   
}
void mousePressed() {  
  mouseRecorded = true; // to record the first sample
  }

void activeSamplingEachTwoSecond() { 
   if (doubleMeasure<=0 && doubleMeasure!=lastSec && mouseRecorded == true) {
  bRecording = true;
  samplers.add( new Sampler( nextSamplePeriod, currTime, mouseX, mouseY ) );
  }
}

void activeSamplingSecondOverRec() { 
   if ( doubleMeasure<=0 && doubleMeasure!=lastSec && mouseRecordedOverRec == true) { 
  bRecordingOverRec = true;
  samplersOverRec.add( new SamplerOverRec( nextSamplePeriod, currTime, xSampler, ySampler ) ); 
  }
}

void keyPressed() {
  if( key == '1' )
    nextSamplePeriod = 1.0;
  else if( key == '2' )
    nextSamplePeriod = 2.0;
  else if( key == '4' )
    nextSamplePeriod = 4.0;
  else if( key == '8' )
    nextSamplePeriod = 8.0;
  else if( key == 'X' ) {
  if( samplers.size() > 0 )
      samplers.remove( samplers.size() - 1 );
  }
}

void keyReleased() {
  if( key == 'R' ){ // to begin overRec the first sample
   mouseRecordedOverRec = true;
  }  
  else if( key == 'Z' ) {
  if( samplersOverRec.size() > 0 )// to delete the second sample
      samplersOverRec.remove( samplers.size() - 1 );
  }
}

Here the class Sampler

class Sampler {
  ArrayList<Sample> samples;
  float startTime;
  float sampleLengthTime;
  float period;
  int playbackFrame;
  
  Sampler( float newPeriod, float now, float x, float y ) {
    samples = new ArrayList<Sample>();
    startTime = now;
    addSample( now, x, y );
    playbackFrame = 0;
    period = newPeriod;
  }
  void addSample( float now, float x, float y ) {
    samples.add( new Sample( now - startTime, x, y ) );
    sampleLengthTime = now - startTime;
    if( sampleLengthTime > period )
      bRecording = false;
      mouseRecorded = false;
    // round up the period to the next power of 2
    // period = sampleLengthTime < 1 ? 1 :
    // pow( 2, max( 0, ceil( log( sampleLengthTime ) / log(2) ) ) );
  }
  void draw( float now ) {
    if( samples.size() < 2 ) return;

    // draw the sample trail
    stroke( 255 );
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samples.get(i-1).x, samples.get(i-1).y );
      vertex( samples.get(i).x, samples.get(i).y );
    }
    endShape();

    // draw the current sample point
    // float st = (now - startTime) % period;
    float st = now % period;
    if( st > sampleLengthTime ) return;
    if( st < samples.get( playbackFrame ).t ) playbackFrame = 0;
    while( samples.get( playbackFrame+1).t < st )
      playbackFrame = (playbackFrame+1) % (samples.size()-1);

    Sample s0 = samples.get( playbackFrame );
    Sample s1 = samples.get( playbackFrame+1 );
    float t0 = s0.t;
    float t1 = s1.t;
    float dt = (st - t0) / (t1 - t0);
 
 //   float x = lerp( s0.x, s1.x, dt ); //     interpolation 'continious datas'
     xSampler = mlerp( s0.x, s1.x, dt, 400 ); // interpolation 'cyclical datas'
     ySampler = mlerp( s0.y, s1.y, dt, 400); // interpolation 'cyclical datas'
       
     yAngle = map (ySampler, 0, 400, 0,  TWO_PI);

    circle ( 100* cos (yAngle)+500, 100*sin (yAngle)+400, 20); // circle to compare Original Sample and the Resample 
  
  }
}

Here the class SamplerOverRec

class SamplerOverRec {
  ArrayList<SampleOverRec> samplesOverRec;
  float startTime;
  float sampleLengthTime;
  float period;
  int playbackFrame;
  
  SamplerOverRec( float newPeriod, float now, float x, float y ) {
    samplesOverRec = new ArrayList<SampleOverRec>();
    startTime = now;
    addSample( now, x, y );
    playbackFrame = 0;
    period = newPeriod;
  }
  void addSample( float now, float x, float y ) {
    samplesOverRec.add( new SampleOverRec( now - startTime, x, y ) );
    sampleLengthTime = now - startTime;
    if( sampleLengthTime > period )
      bRecordingOverRec = false;
      mouseRecordedOverRec = false;
    // round up the period to the next power of 2
    // period = sampleLengthTime < 1 ? 1 :
    // pow( 2, max( 0, ceil( log( sampleLengthTime ) / log(2) ) ) );
  }
  void draw( float now ) {
    if( samplesOverRec.size() < 2 ) return;

    // draw the sample trail
    stroke( 255 );
    beginShape(LINES);
    for( int i=1; i<samplesOverRec.size(); i++) {
      vertex( samplesOverRec.get(i-1).x, samplesOverRec.get(i-1).y );
      vertex( samplesOverRec.get(i).x, samplesOverRec.get(i).y );
    }
    endShape();

    // draw the current sample point
    //float st = (now - startTime) % period;
    float st = now % period;
    if( st > sampleLengthTime ) return;
    if( st < samplesOverRec.get( playbackFrame ).t ) playbackFrame = 0;
    while( samplesOverRec.get( playbackFrame+1).t < st )
      playbackFrame = (playbackFrame+1) % (samplesOverRec.size()-1);

    SampleOverRec s0 = samplesOverRec.get( playbackFrame );
    SampleOverRec s1 = samplesOverRec.get( playbackFrame+1 );
    float t0 = s0.t;
    float t1 = s1.t;
    float dt = (st - t0) / (t1 - t0);
 
    float x = mlerp( s0.x, s1.x, dt, 400 ); // interpolation 'cyclical datas'
    float y = mlerp( s0.y, s1.y, dt, 400 ); // interpolation 'cyclical datas'
       
    float angle = map (y, 0, 400, 0,  TWO_PI);
  
    noStroke();
    fill( 255, 40, 80 );
    circle ( 100* cos (angle)+500+PI, 100*sin (angle)+500+PI, 20);
  }
}