MP3 track won't stop playing at the right time

So this should have been super simple, and yet something is amiss!

So I am using a supersonic range finder to trigger songs at different distances. The first track (player[0]) should come on when the sensor value is between 10 and 30. But instead it comes on at anything above 10, and only turns off under 10. This is true for all the tracks (there are 3 of them) they turn on at anything above there smallest value.

Any ideas? I’m sure it’s just something silly!
Thank you.

 if ((sensors[2] >= 10) && (sensors[2] >= 30)) {
        player[0].pause();   // stop when out of range
      } else {
        if (!player[0].isPlaying())  // if in range and not playing, start playing
          player[0].loop();
      }


      if (!(sensors[2] > 31) && (sensors[2] < 60)) 
      {
        player[3].pause();   // stop when out of range
      } else
      {
        if (!player[3].isPlaying())  // if in range and not playing, start playing
          player[3].loop();
      }


      if (!(sensors[2] > 61) && (sensors[2] < 300)) 
      {
        player[5].pause();   // stop when out of range
      } else
      {
        if ( !player[5].isPlaying())  // if in range and not playing, start playing
          player[5].loop();
      }

with 3 IF you want cover the range of a value from 10 to 300
and divide it into 3 areas.
10 … 30
30 … 60
60 …300
is that correct?


-a- why you mix “>=” and “>” in your code ( do you use float or int values? )
-b- why you use “!()” and only in the second and third range detect?
-c- why you use the player[x].pause if inside range, and .loop outside range,
( that logic would mean 2 out of 3 songs are playing? )

-d- most of all
WHY you not use any PRINT command to check your logic?


so try:

  • take all the song things out of that logic!
  • use a int whatrange = 0; and set it if in range to 1 or 2 or 3
  • print that result
  • based on the result stop all song but the one to play
    ( after the range detect if clause )
1 Like

Hi, Thank you for your response.

Yes, I want 3 different songs to play in 3 ranges (I’ve actually changed the range so I don’t need to keep standing up to trigger the one furthest away.)

There was no reason I mixed > and >= I think its because I’ve re written the code so many times(!) and it wasn’t a big deal if some parts of the range were not covered.

The mix up with (!) inconsistency is again probably as I’ve tried so many different combinations to try to get it to work, that this must have been when I was re writing it.

I do have a print line for the sensor values, and then I listen to what happens. Is that what you mean? Or do you mean to print out something else?

Based on your suggestions I tried this? I took out allot of the ! and did it the other way round. Not sure if I totally followed you though:

     if ((sensors[2] >= 5) && (sensors[2] <= 15)) {
        player[0].loop();  
        player[3].pause();
        player[5].pause();
      } else {
        if (player[0].isPlaying())  
          player[0].pause();
      }

      if ((sensors[2] >= 16) && (sensors[2] <= 30)) {
        player[3].loop();  
        player[0].pause();
        player[5].pause();
      } else {
        if (player[3].isPlaying())  
          player[3].pause();
      }

      if ((sensors[2] >= 31) && (sensors[2] <= 300)) {
        player[5].loop();  
        player[0].pause();
        player[3].pause();
      } else {
        if (player[5].isPlaying())  
          player[5].pause();
      }
    }
  }
}

no, more like ( untested )

int whatrange;
int sensors = 17;

void setup() {
  check_sensor();
}

void draw() {
}

void check_sensor() {
  whatrange = 0;  
  if ((sensors >= 5 ) && (sensors <= 15 )) whatrange = 1;
  if ((sensors >= 16) && (sensors <= 30 )) whatrange = 2;
  if ((sensors >= 31) && (sensors <= 300)) whatrange = 3;
  println("sensors: "+sensors+" whatrange: "+ whatrange);
  play_song();
}  

void play_song() {
  if ( whatrange ==0 ) {
    player[0].pause();  
    player[3].pause();
    player[5].pause();
  }
  if ( whatrange ==1 ) {
    if (! player[0].isPlaying())  player[0].loop();  
    player[3].pause();
    player[5].pause();
  }
  if ( whatrange ==2 ) {
    player[0].pause();  
    if (!player[3].isPlaying())  player[3].loop();
    player[5].pause();
  }
  if ( whatrange ==3 ) {
    player[0].pause();  
    player[3].pause();
    if (!player[5].isPlaying())  player[5].loop();
  }
}


Hi that looks interesting.

I’m not sure where to put the check_sensor functions and Play song. If I put them inside my “void serial” event then it doesn’t like it. but If I put it outside that it can’t see the sensor data / array.

import processing.serial.*;    // Serial port for communication with Arduino
Serial myPort;     

import ddf.minim.*;
import ddf.minim.signals.*;  // Minim library that provides sine wave
import ddf.minim.spi.*; // for AudioRecordingStream

Minim minim;
AudioOutput out;  
AudioPlayer[] player = new AudioPlayer[8];

int whatRange;

float freq;           // sine wave frequency. Making a sine wave is different from playing a sample or track. Minim is actualy creating the sound live using the data. 
float amp;            // sine wave amplitude
SineWave sine;        // a function to generate the values of a sine wave

void setup()
{

  check_sensor();
  minim = new Minim(this);

  player[0] = minim.loadFile("air.mp3"); 
  player[1] = minim.loadFile("bachOrgan.mp3"); 
  player[2] = minim.loadFile("barbarShop.mp3"); 
  player[3] = minim.loadFile("dingding.mp3"); 
  player[4] = minim.loadFile("gentlePiano.mp3"); 
  player[5] = minim.loadFile("horror.mp3"); 
  player[6] = minim.loadFile("organSing.mp3"); 
  player[7] = minim.loadFile("ragtime.mp3"); 

  myPort = new Serial(this, Serial.list()[2], 9600);
  myPort.bufferUntil('\n');
  size(640, 240);
  out = minim.getLineOut(Minim.STEREO);  
  sine = new SineWave(440, 0.5, out.sampleRate()); 

  sine.portamento(200);
  out.addSignal(sine);
  out = minim.getLineOut();
}

void draw()
{
  sine.setFreq( freq ); 
  sine.setAmp( amp ); 

  // the following just drawers the sign wave of the sounds that are being created. This was really helpful visual for debugging and testing. 

  // erase the window to black
  background( 0 );
  // draw using a white stroke
  stroke( 255 );
  // draw the waveforms
  for ( int i = 0; i < out.bufferSize() - 1; i++ )
  {
    // find the x position of each buffer value
    float x1  =  map( i, 0, out.bufferSize(), 0, width );
    float x2  =  map( i+1, 0, out.bufferSize(), 0, width );
    // draw a line from one buffer position to the next for both channels
    line( x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
    line( x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
  }  

  // float songPos = map( filePlayer.position(), 0, filePlayer.length(), 0, width );

  stroke( 255, 0, 0 );
  //  line( songPos, 0, songPos, height );

  //
  //text( "loopCount: " + filePlayer.loopCount(), 15, 15 );
}



// The following is where processing takes in the serial port data, cleans it up, and uses it to make music. 

void serialEvent (Serial myPort) { // this using an interupt. It pauses the loop, and then returns to it. It is often better to do all actions in the loop. 
  // get the ASCII string:
  String inString = myPort.readStringUntil('\n');

  if (inString != null) {
    //   println(inString);
    // trim off any whitespace:
    inString = trim(inString);
    // split the input string at the commas
    // and convert the sections into integers:
    int sensors[] = int(split(inString, '\t'));
    // if we have received all the sensor values, use them:
    if (sensors.length == 3) {

      print(sensors[0], sensors[1], sensors[2]);

      /* 
       
       Sensor 0 = Cap sense
       Sensor 1 = Presure
       Sensor 2 = Distance
       
       */

      //    amp = map(sensors[3], 80, 3000, 0, 1); // this needs to be edited at every new location! Cap sense tends to change. 
      amp = 1;
      freq = map(sensors[0], 80, 3000, 110, 880);

      // distance sensor::
      // This is code RIchard helped me write. ! = not. So if it is not in that range, 
      // pause air. otherwise, if air is not playing, play air. 


      // I made these "double if statements" instead of if (this && this) is not true, as before it would never turn off


      void check_sensor() {
        whatRange = 0;

        if ((sensors [2] >= 5 ) && (sensors [2] <= 15 )) whatRange = 1;
        if ((sensors [2] >= 16) && (sensors [2] <= 30 )) whatRange = 2;
        if ((sensors [2] >= 31) && (sensors [2] <= 300)) whatange = 3;
        println("sensors: "+sensors [2]+" whatrange: "+ whatRange);  
        play_song();
      }

      void play_song() {
        if ( whatRange ==0 ) {
          player[0].pause();  
          player[3].pause();
          player[5].pause();
        }
        if ( whatRange ==1 ) {
          if (! player[0].isPlaying())  player[0].loop();  
          player[3].pause();
          player[5].pause();
        }
        if ( whatRange ==2 ) {
          player[0].pause();  
          if (!player[3].isPlaying())  player[3].loop();
          player[5].pause();
        }
        if ( whatRange ==3 ) {
          player[0].pause();  
          player[3].pause();
          if (!player[5].isPlaying())  player[5].loop();
        }
      }
    }
  }
}