(saving sounds on magnetometer values) Problems updating PVector Arrays


#1

Currently I am making an android app where you can save soundfragments on positions in 3d space (trigger files on certain magnet values(x,y,z)). Started with a working version where I didnt use arrays at all, but that got me into some problems later on. I use the ketai libraries (credits and MANY thanks, lord Ketai).
I describe the problem in the lowest section. Some help and feedback/critique would be very much appreciated! Feel free to ask any questions or the .pde file to test it for yourself. You can change magnet values with the phones position or a magnet.

TL;DR 1: Updating Vector arraylists and calculating distances between saved values and current value, gives “Attempt to read from field ‘float processing.core.PVector.x’ on a null object reference”.
2: I want to change currently played sounds when coming near a saved location, but have to call .stop and .loop again which leads to constant draw problems.

Main body: (NOT WHERE the problem is)

import android.view.MotionEvent;
import ketai.ui.*;
import ketai.sensors.*;
KetaiGesture gesture;
KetaiSensor sensor;

//import cassette.audiofiles.SoundFile;
import processing.sound.*;
SoundFile file;

int lijst = 20;
SoundFile[] geluid = new SoundFile[lijst];
//FIELDS: Magnet vector locations
PVector magneticField = new PVector();    //Sensor values from ketai
PVector neutralField = new PVector(); //Callibrated sensor values (set to 0 when no magnets near the phone)
PVector normalizedField = new PVector(); //Magnet values that are used for locations etc (magneticField - neutralField)
//Neutral field callibration
float fieldMag; 
float fieldPrev;
//LOCATE: Detection range for file location.
Boolean ja = false;
int listen = 10;
int range = listen*2;
int nnn = 0; 

//Audio file vector locations + distance between location and current values
PVector[] distance = new PVector[lijst]; 
PVector[] location = new PVector[lijst]; 

float[] dist = new float[lijst];
int num = 0;

//Timer for callibration
int step = 0; 
int timereset = 0; 
long time=0; 

ArrayList<Thing> things = new ArrayList<Thing>();

void setup()
{  fullScreen();  textAlign(CENTER, CENTER);  textSize(displayDensity * 28);
  sensor = new KetaiSensor(this);  sensor.start();  sensor.list();
  gesture = new KetaiGesture(this);

  geluid[1] = new SoundFile(this, "bass.wav");
  geluid[2] = new SoundFile(this, "tom.wav");
  geluid[3] = new SoundFile(this, "closed1.wav");
  geluid[4] = new SoundFile(this, "closed2.wav");
  geluid[5] = new SoundFile(this, "open.wav");
  geluid[6] = new SoundFile(this, "ride.wav");
  geluid[7] = new SoundFile(this, "snare1.wav");
  geluid[8] = new SoundFile(this, "snare2.wav");
  
  file=geluid[1];  file.loop(); //Currently needed so it doesnt crash on a call loop on null object ref
}
void draw(){    background(10);  fill(255);  textSize(50);  textAlign(LEFT);
//CALIBRATE I: Find normal: field without magnetic influence./ not turned
  fieldMag = magneticField.mag();
  if (step == 0) {    if (timereset == 0) { 
      time = millis();
      timereset = 1; 
      fieldPrev = fieldMag;
    }    if (millis() - time >= 1500) { //Time for calibration/setting average
      if (fieldMag >= fieldPrev - 1 && fieldMag <= fieldPrev + 1) {
        step = 2;
        neutralField.x = magneticField.x;
        neutralField.y = magneticField.y;
        neutralField.z = magneticField.z;
        timereset = 1;
      } else {
        timereset=0;
        step =0;
      } } }}

THIS IS where the trouble starts, I add a new object (Thing) with location of the current Vector magnet values
and use int ‘num’ to connect it to a sound. When you double tap the screen it saves a sound to the current x,y,z and num counts up to place the next object. “ja = true;” is used so it doesnt crash later in the following code reading a null object ref, which is where the actual problem is.

void onDoubleTap(float x, float y) { 
    num++; 
    things.add(new Thing(normalizedField.x, normalizedField.y, normalizedField.z, num));
    ja = true; }

class Thing{
  public Thing(float cx, float cy, float cz, int num)  {
    location[num] = new PVector(cx,cy,cz);
  }

THE PROBLEM.
I TRY TO calculate the distance between the current magneto values (PVector normalizedField) and the location Vectors of ‘things’ (as many as there are created by double tapping). When the distance(for any placed object) is smaller than float ‘range’, the sound should play.
As of now, I’m constantly updating the location PVector array values and the calculated distance for each ‘thing’ placed by using the for loop with ''int i < [this should be the amount of things placed]".
The problem is that I get "Attempt to read from field ‘float processing.core.PVector.x’ on a null object reference
" when I change “if num>2” to “>1” or change “i<4” in the for loop to a larger number, to match the amount of sounds (int ‘list’ array size).
SECOND PROBLEM
Im changing the sounds by setting the SoundFile class <file = geluid[i]> (found in the main body)
To change the sounds I need to call file.stop(); change the sound and then re-call file.loop();. and right now it constantly draws the .loop(), crashing the program. However I cant yet think of how I can fix this, in the pre-arrayification version I managed to do it with if(distance1 < range && distance1 < distance 2 && distance1 <distance3 etc, etc, and this for all different distances, a lot of code and made the program not so smooth with more than 8 sounds or so.

 void memory() {
  if (num>2) { 
    for (int i=1; i < 4; i++) {
      dist[i] = PVector.dist(normalizedField, location[i]);
      if(dist[i] < range){
        if(nnn==0){
        file.stop();
        file = geluid[i];
        nnn=1;
        file.loop();
        }
      }
      if(dist[i]>range){
        if(nnn==1){
        file.stop();
        nnn = 0; } }      
    }
  }
}