Can't get other song to be replaced

***The code below has an invisible button in the middle when pushed you can select a new song to play replacing the wave in the background. The problem that I am having is I want the new song to replace the old one, but when I pick a new song a new wavelength forms. I only want 1 wave in the background moving with the song playing that the user chooses. Having trouble with this any suggestions? ** Note: I would’ve posted this with my last post but this is different question regarding the code so I thought I’d post this separate. Really want to practice in processing sorry for so many posts, thanks!

//minim is the audio library allowing for us to play and pull the music in
import ddf.minim.*;


import ddf.minim.spi.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;

//all of the songs that we have
AudioPlayer song1;
AudioPlayer song2;
AudioPlayer song3;
AudioInput in;

float buttonX;
float buttonY;




Minim minim;

ArrayList<Songs> s;
int k;

String filename;

boolean isSelected = false;

//number of stars & speed is declaring the varible for the speed of the stars
Star[] stars = new Star[100];
float speed;

//creating a filler variable for the color of the lines, then sets the height and 
//width variable for the button
color c;
float buttonH = 50;
float buttonW = 200;

// number of lines in x & y direction, float magitude variable is for wave,boolean is declaring the variable for the if statement involving line,
//the float variable is declaring the parameteres for the line movement
int linesX = 40; 
int linesY = 26; 
float magnitude;
boolean voice = false;
float stepsX, stepsY, radius, intensity, movement, last_sum, scale, factor, wave, sum;


//audioplayer is to play all of the songs and the button numbers are to position the button on the top left of the screen
AudioPlayer player;
boolean play = true;
int button_x = 40, button_y = 40, button_sz = 20;


//only runs once, full screen makes the screen full screen, noSmooth is for making the lines of the wave jagged
void setup() {
  fullScreen();
  noSmooth();
  
//once the stars position is equal to >0 it is reset randomly back to the top of the screen, the for loop takes into account the full length of 
//the star rather than resetting it as soon as it hits the bottom
  for (int i = 0; i < stars.length; i++) {
     stars[i] = new Star(); 
}  
 
  
//tells minim to locate the song file and play it, then song1,2,3 play each of the mp3 files, .play plays the whole song, .rewind rewinds current song and plays the new song
//keep the wavelength within the screen 
  minim = new Minim(this);
  
  player=minim.loadFile("I Lived - OneRepublic Piano Tribute.mp3");


  
  song1 = minim.loadFile("I Lived - OneRepublic Piano Tribute.mp3");
  song1.play();
  song1.rewind();
  factor = float(width)/song1.bufferSize();
  
 
 s = new ArrayList();

  textSize(24);

  frame.setResizable(false);

  buttonX = width - width/2 - buttonW/2;
  buttonY = height/2 - buttonH/2;

  // Minim stuff
  minim = new Minim(this);
}


//this is for the button so when its pushed it plays and pauses the songs. 
void mousePressed(){
  if( mouseX > button_x && mouseX < button_x + button_sz &&
      mouseY > button_y && mouseY < button_y + button_sz)
  {
     play = !play;//will switch false/true each click
  }
}


//continuously executes the line of the code contained in its block unit the program is stopped, noCursor just makes the cursor diappeared
void draw(){ 

//link the value of the speed variable to the mouse position
{ 
  speed = map(mouseX, 0, width, 0, 20);
  background(0);
  
//moving the center of the screen from the top left corner to the center of the canvas
  translate(width/2, height/2);
  
//draw each star, running the update method to its position and show method to show it on the canvas
 for (int i = 0; i < stars.length; i++) {
   stars[i].update();
   stars[i].show();
}
}
 
 {

//moving the center of the screen from the top left corner to the center of the canvas
   translate(-width /2, -height /2); 
   c = color(170 + wave/2, wave*5, 255,255);
  fill(random(0,255), random(0,255), random(0,255));
   stroke(random(0,255), random(0,255), random(0,255));
   strokeWeight(2);
   sum = 0; 
   
// creates sound waves that change in frequency and amplitude, initially makes it so the array "i" is less than that of the songs buffer size or its bass. The "if" and "else" statements 
//lock the line on the left and right side of the screen at exactly the middle y value of the entire screen. It brings in factor just putting all of the parameters of the line in one place
  for (int i = 0; i < song1.bufferSize() - 1; i++)
  {
    if (voice) {
      line(i*factor, height/2 + in.left.get(i)*last_sum + 1, i*factor+1, height/2 + in.left.get(i+1)*last_sum + 2);
      sum += abs(in.left.get(i));
    } else {
     line(i*factor, height/2 + song1.left.get(i)*last_sum + 1, i*factor+1, height/2 + song1.left.get(i+1)*last_sum + .05);
     sum += abs(song1.left.get(i));
    }
  }
 

  rect(buttonX, buttonY, buttonW, buttonH);
fill(255);
  textAlign(CORNER);
  text("Import File", buttonX+600, buttonY+300);
  

  if (isSelected) {
    s.get(k).waveform();
  }
}

//makes the two sections wavelength equal 
  last_sum = sum;
    {
     
//randomizes the color for the moon
  fill(random(0,255), random(0,255), random(0,255));

//draws the moon shape, and noStroke gives it no outline
  ellipse(width /2, height /2, 500, 500);
  noStroke();
}

 {
//puts the moon the in the center, and fills it the color white, and noStroke makes it have no outline, the next ellipse statement is for the black circle on top of the white
// that makes the cresent shape
  ellipseMode(CENTER);
  fill (0);
  ellipse(width /2 -50,height /2 -50, 460, 450);
  noStroke();
 }
{
//makes the thickness of all lines to 2
   strokeWeight(2); 
}

//this is for the outline of the button the pink color is the stroke and fill is for the blue/purlish color, rect is for the placement of the button on the screen
  stroke(255, 0, 255);
  fill(50, 0, 120);
  rect(button_x, button_y, button_sz, button_sz);
 
//this if statement is to play the songs when the button is pushed and under it is to pause the songs when the button is pushed again
// play = play all 3 songs, pause= pause all 3 songs
 if (play) {
    player.play();  
    song1.play();
   
 }
 else {
    player.pause();
    song1.pause();

 }
   
  }
  // stop minim and the player.
void stop() {
  player.close();
  minim.stop();
  super.stop();
}
void mouseClicked() {
  if (mouseX>buttonX && mouseX < buttonX+buttonW && mouseY > buttonY && mouseY < buttonY+buttonH) {
    selectInput("Import music file", "fileSelected");
  }
}

//Taken from Processing.org
void fileSelected(File selection) {
  if (selection == null) {
    println("Window was closed or user hit cancel");
  } 
  else {
    filename = selection.getAbsolutePath();
    s.add(new Songs(player, filename, "Filename"));
    isSelected = true;
  }
}

Hi! You are adding a new song to an ArrayList when you choose a file. If you only want one song available at all times, then you could get rid of the ArrayList<Songs> s and use just Songs s. But I assume you had something in mind when creating a collection of songs instead of just one?

If you don’t want to touch any of the code, what you can do is call s.clear(); right before calling s.add. That will remove all previous songs. But it defeats the purpose of having an ArrayList.

1 Like

This is what I was trying to do: In the code posted you will notice that I have the song I Lived - OneRepublic Piano Tribute. When this animation plays a moon in the middle randomly changes color and a wave in the behind it moves according to the songs frequency. Also you will notice in the top left corner I already have a button that stops and plays the music. All of this is exactly how I wanted but I’m trying to have a another button ( this other button is there in the middle of the moon where the black space is if you click there you will see its there but I’m not sure why its invisible). So I’m trying to get that button to replace the song I Lived - OneRepublic Piano Tribute and replace it with the new one so that the same wave from before will now play according to the frequency of the new song selected. So basically I’m trying to move that invisible button to the side and make is visible I’m not sure why when I click its there but you can’t see it at the moment & have the current song replaced if the user decides to pick a new song. I don’t know if this better explains it but that’s what I’m trying to do and am having trouble with. :confused:

This is a minimal example that plays one song until you click the mouse and choose another song. Then it starts playing the new song. Notice that there is just one AudioPlayer.

import ddf.minim.*; 

Minim minim;
AudioPlayer player;

void setup() {
  minim = new Minim(this);
  player = minim.loadFile("~/Music/sorted/Stephan Micus/The Garden of Mirrors/02 Passing Cloud.mp3");
  player.play();
}

void draw() { }

void mouseClicked() {
  selectInput("Import music file", "fileSelected");
}

void fileSelected(File selection) {
  if (selection == null) {
    println("Window was closed or user hit cancel");
  } else {
    player = minim.loadFile(selection.getAbsolutePath());
    player.play();    
  }
}

I notice one possible problem in your code. You click the mouse to toggle play. If play is true, every time draw is called, it will try to play the songs, I assume from the beginning. So maybe there’s no sound heard? I think it might be better to play/pause the songs inside the mousePressed function, and not inside draw, because you probably want to play it or pause it once when the mouse is clicked, not 60 times per second.

1 Like