Adding import button to music player

2019-08-10 23:20发布

问题:

I'm trying to make it possible to make a functional import button, by this I mean I click the button, the file browser pops up and I can click a song then the player can play it. Just like any other music player. Here is a basic view of my code so far excluding the classes:

import ddf.minim.spi.*;
import ddf.minim.*; 
import ddf.minim.signals.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
import ddf.minim.ugens.*;
boolean play;
boolean repeat;
int k;
String filename;//
Minim minim;
AudioPlayer player;

Pics p;
Mechs m;
Importbt b;
ArrayList<Songs> s;
int i=0;
void setup() {
size(600, 400);
b=new Importbt();
m=new Mechs();
p=new Pics();
p.Thepics();

minim=new Minim(this);
s = new ArrayList();
s.add(new Songs(player, "SONG 1", "SONG 1"));
s.add(new Songs(player, "SONG 2", "SONG 2"));
s.add(new Songs(player, "SONG 3", "SONG 3"));
s.add(new Songs(player, "SONG 4", "SONG 4"));
k = s.size()-1;
}
void draw() {
background(0);
p.getFunction();
}

void fileSelected(File selection) {
if (selection == null) {
} 
else {
filename = selection.getAbsolutePath();
player = minim.loadFile(filename);//loads the file
// s.add(k, new Songs(player, filename, "a song"));
//s.get(k).playmusic();
s.add(new Songs(player, filename, "ftyu"));
s.get(k).waveform();//function from my songs class
player.play();//plays the file

As for my class if its needed

class Songs {
AudioPlayer song; 
String directory;
String songName;
Songs(AudioPlayer song, String directory, String songName) {

song=minim.loadFile(directory);

this.song=song;
this.songName=songName;
}
void waveform() {
for (int j = 1; j < song.bufferSize() - 1; j++)
{
  if (j>0) {

    line(j, 214  + song.left.get(j)*50, j+1, 214 + song.left.get(j+1)*50);
    //waves from the left.
    stroke( 255, 0, 0 );  //this is the colour of the first line (red)
    line(j, 214 + song.right.get(j)*50, j+1, 214 + song.right.get(j+1)*50);
    //waves from the right.
    stroke(255, 255, 0);

  }
}

回答1:

Here's something to get you going:

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

float buttonX;
float buttonY;
float buttonW;
float buttonH;

Minim minim;
AudioPlayer player;

String filename;

void setup() {

  textSize(24);

  frame.setResizable(false);

  background(255);

  size(600, 200);

  fill(0);
  stroke(0);
  noFill();

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

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

void draw() {

  background(255);
  fill(0);

  rectMode(CORNER);

  rect(buttonX, buttonY, buttonW, buttonH);

  fill(255);

  textAlign(LEFT);
  text("Import File", buttonX+35, buttonY+30);
}

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();
    player = minim.loadFile(filename);
    player.play();
    println("User selected " + filename);
  }
}

// stop minim and the player.
void stop() {
  player.close();
  minim.stop();
  super.stop();
}

This is a very simple example. All this does is creates objects for Minim and AudioPlayer and then uses the file selection mechanism to feed the path and name of the file to loadFile(filename). Then if the file is a legitimate audio file (I only tested with a .wav file) then it plays it. After it is done, the player is stopped.

Keep in mind that this does not do any error checking or anything so if you chose a .jpeg file, for example, it will throw exceptions. You should play with these things to try and see how you can streamline your player.

One thing you should try and understand is that this is all very straightforward. The filename is simply a String and nothing extremely complicated.

You can find a tutorial for Minim here: http://artandtech.aalto.fi/wp-content/uploads/2012/06/minim.pdf

UPDATE: SINE WAVES WORKING WITH THE SELECTED SONG

I have updated my code that I provided here to work with the wave thing that you have going. I added a boolean which becomes true when a file is selected. Now you will have to tweak this code to work with multiple files. This is just an example.

UPDATE 2: IMPLEMENTED THE CODE TO WORK WITH YOUR SONGS CLASS

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

float buttonX;
float buttonY;
float buttonW;
float buttonH;

Minim minim;
AudioPlayer player;
ArrayList<Songs> s;
int k;

String filename;

boolean isSelected = false;

void setup() {

  s = new ArrayList();

  textSize(24);

  frame.setResizable(false);

  background(255);

  size(600, 600);

  fill(0);
  stroke(0);
  noFill();

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

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

void draw() {

  background(255);
  fill(0);

  rectMode(CORNER);

  rect(buttonX, buttonY, buttonW, buttonH);

  fill(255);

  textAlign(LEFT);
  text("Import File", buttonX+35, buttonY+30);

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

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;
  }
}

// stop minim and the player.
void stop() {
  player.close();
  minim.stop();
  super.stop();
}

class Songs {
  AudioPlayer song; 
  String directory;
  String songName;
  Songs(AudioPlayer song, String directory, String songName) {

    song=minim.loadFile(directory);    

    this.song=song;
    this.songName=songName;
    song.play();
  }
  void waveform() {
    for (int j = 1; j < song.bufferSize() - 1; j++)
    {
      if (j>0) {

        line(j, 214  + song.left.get(j)*50, j+1, 214 + song.left.get(j+1)*50);
        //waves from the left.
        stroke( 255, 0, 0 );  //this is the colour of the first line (red)
        line(j, 214 + song.right.get(j)*50, j+1, 214 + song.right.get(j+1)*50);
        //waves from the right.
        stroke(255, 255, 0);
      }
    }
  }
}

The reason you see a flash of red and then nothing the way you had your code set up was because it reads the waveform() method and goes through the for loop really fast and then moves on to the rest of the operations like playing the song. Putting it in draw() like I've done helps you avoid that.