Listening to music / Watching a Roller Coaster Visualization

So, I made this basic silly visualization that attempts to make one feel like they're on a roller coaster. Using a .wav file's music / amplitude, "tracks" are created that go up and down in 3D and you "feel" like you're going forward. If you copy the code and replace "cosmos.wav" with your .wav file, that's all you should have to do. Best pick a file with lot's of ups and downs to get a sense of it.

It's pretty rough but I was wondering if anyone had any design suggestions. I can't get out of this zero-sum game between the roller coaster track lengths and the reaction time. Ideally, it would be flowing through the tracks so fast that you would see a lot of the track but having the screen be right there with it. It's also hard to compromise between how smooth it feels and how reactive it is, in general. I feel that I can only get so far to a good feeling with this current design and I should redesign it differently somehow (maybe using translations instead to simulate movement... for example). But I'm a coding and Processing beginner so I don't have many good ideas.

Let me know if you have any code / design suggestions. Greatly appreciated. Thanks.

import ddf.minim.analysis.*;
import ddf.minim.*;
import com.google.common.collect.EvictingQueue;
import com.google.common.primitives.Floats;

EvictingQueue ampTrail;
EvictingQueue cameraDifferenceShifting;
EvictingQueue drawingAmpTrailHistoryOfSmoothAmps;

float previousNumber;

Minim       minim;
AudioPlayer soundFile;
FFT         fft;

void setup() {
  size(1024, 600, P3D);
  frameRate(60);
  
  minim = new Minim(this);
  soundFile = minim.loadFile("cosmos.wav", 1024);
  soundFile.play();

  previousNumber = 0;
  
  ampTrail = EvictingQueue.create(100); // how smooth vs. responsive ampTrail should be
  cameraDifferenceShifting = EvictingQueue.create(50); // how smooth camera movements should be
  drawingAmpTrailHistoryOfSmoothAmps = EvictingQueue.create(100); // how long the path
}

float translateRange(float oldVal, float oldMin, float oldMax, float newMin, float newMax) {
  float slope = (newMax - newMin) / (oldMax - oldMin);
  return (slope * (oldVal - oldMin)) + newMin;
}

float findAverage(float[] lastValues) {
  int amtToProcess = lastValues.length;
  float sum = 0;
  for (int i = 0; i < amtToProcess; i++) {
    sum = sum + lastValues[i];
  }
  float avg = sum / amtToProcess;
  return avg;
}

float getSmoothAmplitude0to100() {
  float average = (soundFile.left.level() + soundFile.right.level()) / 2;
  float translateToCanvas = translateRange(average, 0, 0.6, 0, height);
  translateToCanvas = height - translateToCanvas;
  ampTrail.add(translateToCanvas);
  float currentAverage = findAverage(Floats.toArray(ampTrail));
  return currentAverage;
}

float drawTrack() {
  noFill();
  float leftTrackX = -150 + (width / 2);
  float rightTrackX = 150 + (width / 2);
  float[] ampTrailArray = Floats.toArray(drawingAmpTrailHistoryOfSmoothAmps);
  int arrLength = ampTrailArray.length;
  // left track
  beginShape();
  for (int i = arrLength - 1; i > 0; i--) {
    curveVertex(leftTrackX, ampTrailArray[i], -i);
  }
  endShape();

  // right track
  beginShape();
  for (int i = arrLength - 1; i > 0; i--) {
    curveVertex(rightTrackX, ampTrailArray[i], -i);
  }
  endShape();
  return ampTrailArray[0];
}

float findDifference(float currentNumber) {
  float difference = currentNumber - previousNumber; //global variable
  previousNumber = currentNumber;
  return difference;
}

float correctDifference(float difference) { // adjusting things here to make things visible...
  difference = translateRange(difference, -5, 5, -1000, 1000);
  cameraDifferenceShifting.add(difference);
  float currentAverage = findAverage(Floats.toArray(cameraDifferenceShifting));
  return currentAverage;
}

void draw()
{
  background(255);
  
  // make some visual consistent thing to see how much camera is moving
  fill(150);
  ellipse(width / 2, height / 2, 100, 100);
  
  // drawing the tracks and updating them
  float smoothAmp = getSmoothAmplitude0to100();
  drawingAmpTrailHistoryOfSmoothAmps.add(smoothAmp);
  
  //trying to mimic the sensation of being "in" the coaster
  float currentNumber = drawTrack();
  float difference = findDifference(currentNumber);
  float correctedDifference = correctDifference(difference);
  camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0), // eye
         width/2.0, (height/2.0) + (correctedDifference), 0, // center
         0, 1, 0); // up    
}

Answers

Sign In or Register to comment.