How do I play the same soundfile multiple times simultaneously?

edited March 2017 in Library Questions

It sounds a bit strange, but basically I want a sound effect to play every time something special happens in my sketch, but the results vary from the soundfile only playing ones to cases where later attempts to play the file innterupts earlier instantations. I've tried both Minim and the processing Sound library, but I haven't been able to make it work. How could this be done?

Tagged:

Answers

  • soundfile only playing once

    you need to rewind files when they finish.

    later attempts to play the file innterupts earlier instantations

    you'll need multiple objects using the same source file, i think.

    post some code. anything else just requires us to guess what you've done.

  • This is the code:

    import ddf.minim.*;
    AudioPlayer player;
    Minim minim;
    
    String song="Jump.mp3";
    
    void setup() {
      // randomSeed(int(random(1, 10000)));
      fullScreen();
      background(255);
      frameRate(60);
      minim = new Minim(this);
      player = minim.loadFile(song);
    }
    
    void draw() {
      if (keyPressed) {
       player.rewind();
        player.play();
    
      }
    
    }
    

    Rewind does help, but it doesn't play the same file over itself. I'd like to be able to use multiple objects, but I potentially want to play around 1000 files at once, and loading the file multiple times drains memory quite drastically...

  • edited March 2017 Answer ✓

    Declare an AudioPlayer[] global variable.
    So you can store all of your loadFile() within setup() and use them everywhere else.

  • Demo below.

    Kf

    import ddf.minim.*;
    AudioPlayer[] mplayer;
    Minim minim;
    
    //String[] songs={"cr1.mp3", "co2.mp3", "dj3.mp3"};
    String[] songs={"cr1.mp3", "cr1.mp3", "cr1.mp3"};
    
    
    void setup() {
      // randomSeed(int(random(1, 10000)));
      size(200, 200);
      background(255);
      frameRate(60);
      minim = new Minim(this);
      mplayer=new AudioPlayer[3];
    
      for (int i=0; i<songs.length; i++) {
        mplayer[i] = minim.loadFile(songs[i]);
        mplayer[i].play();
      }
    }
    
    void draw() {
    }
    
    
    void mouseReleased() {
    
      int v=int(random(songs.length));
      mplayer[v].rewind();
      mplayer[v].play();
      println("YES... lucky one is "+v);
    }
    
  • edited March 2017

    Thank you kfrajer! But while this does work, it might still run low on memory if I want to be certain that a large number of files are played at the same time. Is there no way to only load the file once?

  • Hmmm loading the file once and playing the same resource multiple times, not sure if it is possible. An analogy is that instead of having an army, you want to have a single soldier and tell it to go right while at the same time telling it to go left?

    Maybe if you provide more details about the nature of your projects, your files and how many you want to play, then other forum goers could add additional comment on your challenge.

    Kf

  • Well, basically I'm drawing multiple quadratic functions and whenever two of them intersect I want to play a sound, but when I've got about 50 of them it feels a bit like I'm wasting space if I load files for all of the lines separately. It does work when I do that though, so this may just be something I have to accept...

  • edited March 2017

    @Eiroth -- It is possible. Using the minim library, load a Sampler and allocate up to a certain number of "voices" for multiple simultaneous playback.

    See this recent discussion for an example:

  • I potentially want to play around 1000 files at once

    This seems very unlikely, unless your sound sample is quite long. At a certain time resolution there would be no perceptual difference between 50 or 100 overlapping samples and 1000.

    Keep in mind that samples triggered in the same frame are identical -- you only need one. If you have 60 fps, and are triggering new overlapping samples at 1/60th sec rate, then your sample would need to be over 16 seconds long with new sampling triggered every single frame before you would need 1000 voices.

    Even then I doubt you could tell much difference between that audio mess and the audio mess that you would get from triggering 500 voices at 30fps -- they might sound almost identical (although this is outside my expertise, and you would need to test it).

    If you have a normal 2-3 second sample at 60 fps then 180 voices is the outer limit, and I would guess you need far less.

  • edited March 2017

    Thanks so much for the help guys! If anyone's interested, this is probably how the code turned out. It's pretty messy but it works:

    import ddf.minim.*;
    
    
    Minim minim;
    
    float[] x = new float[7];
    float[] y = new float[x.length];
    float[] gx = new float[y.length];
    float[] gy = new float[gx.length];
    float[] a = new float[gy.length];
    float[] b = new float[a.length];
    float[] c = new float[b.length];
    color[] rgb= new color[c.length];
    int count = 0;
    int t = 0;
    
    // Intersect points
    float[][] hitsX=new float[c.length][c.length];
    float[][] hitsY=new float[c.length][c.length];
    boolean[][] drawn=new boolean[c.length][c.length];
    boolean drawnreset = false;
    
    
    
    boolean calculate=true;
    int songs=10;
    AudioPlayer[] player= new AudioPlayer[songs];
    String song = "ting.mp3";
    int play=0;
    
    void setup() {
      // randomSeed(2);
      strokeWeight(1);
      stroke(0);
      line(- width / 2, 0, width / 2, 0);
      line(0, - height / 2, 0, height / 2);
    
      // initilization
      fullScreen();
      background(255);
      frameRate(50);
      minim = new Minim(this);
      for (int i=0; i<songs; i++) {
        player[i] = minim.loadFile(song);
      }
      //a[0]= -1;
      //b[0]=4;
      //c[0]=-2;
      //a[1]= 1;
      //b[1]=-4;
      //c[1]=-2;
    
      //generates the function
      for (int n = 0; n < y.length; n++) {
        x[n] = -1 * width/2;
        y[n] = 0;
        gx[n] = -1 * width/2;
        gy[n] = 0;
        a[n]= random(-0.01, 0.01);
        b[n]=random(-2, 2);
        c[n]=random(-200, 200);
        rgb[n]=color(random(255), random(255), random(255));
      }
      intersectcalc();
    
      //REMOVE
    }
    
    void draw() {
      // background "settings"
      translate(width / 2, height / 2);
    
    
      for (int k=0; k<11; k++) {
        for (int n = 0; n < x.length; n++) { 
          strokeWeight(1);
          stroke(rgb[n]);
          noFill();
          x[n] += 1;
    
          // draws graph
          y[n] = a[n] * (x[n] * x[n]) + b[n] * x[n] + c[n];
          line(gx[n], gy[n], x[n], y[n]);
          gx[n] = x[n];
          gy[n] = y[n];
    
          //textAlign(LEFT);
          //textSize(30);
          //fill(0);
          //text(y[n], x[n], y[n]);
    
          // makes a new background
          if (x[n] > width / 2) {
            a[n] = random(-0.001, 0.001);
            b[n] = random(-5, 5);
            c[n] = random(- height / 2, height / 2);
            x[n] = -1 * width/2;
            y[n] = 0;
            gx[n] = -1 * width/2;
            gy[n] = 0;
            background(255);
            t = 0;
            for (int i = 0; i < c.length; i++) {
              for (int o = 0; o < c.length; o++) {
                drawn[i][o]=drawnreset;
              }
            }
    
            //Caculates intersections
            intersectcalc();
          }
    
          if (t < width / 2) {
            line(t, -5, t, 5);
            line(-t, -5, -t, 5);
            line(-5, t, 5, t);
            line(-5, -t, 5, -t);
    
            if (t != 0) {
              stroke(127, 50);
              line(t, - height / 2, t, height / 2);
              line(-t, - height / 2, -t, height / 2);
              line(-width / 2, t, width / 2, t);
              line(-width / 2, -t, width / 2, -t);
    
    
              textSize(10);
              textAlign(CENTER, TOP);
              fill(0);
              text(t, t, 6);
              fill(0);
              text(-t, -t - 3, 6);
              textAlign(CENTER, RIGHT);
              fill(0);
              text(t, -20, t + 3);
              fill(0);
              text(-t, -20, -t + 3);
            }
    
            t += 100;
          }
    
    
    
    
          //intersects
    
          // end of intersects
        }
        for (int i=0; i<c.length; i++) {
          for (int o=0; o<c.length; o++) {
            if (i !=o) {
              if (hitsY[i][o] < height/2 && hitsY[i][o] > -height/2 && hitsX[i][o] > -width/2 && hitsX[i][o]< width/2 && x[i] >= hitsX[i][o] && drawn[i][o]==false && y[i]<(height/2) && y[i]>-height/2 && y[o]<(height/2) && y[o]>-height/2 && y[o]<(height/2) && y[o]>-height/2) {
    
                stroke(0);
                ellipse(hitsX[i][o], hitsY[i][o], 5, 5);
                player[play].rewind();
                player[play].play();
                play++;
                count++;
                textAlign(TOP);
                textSize(20);
                fill(0);
                text("X=" + hitsX[i][o], hitsX[i][o], hitsY[i][o]);
                text("Y=" + hitsY[i][o], hitsX[i][o], hitsY[i][o] + 18);
    
    
                drawn[i][o]=true;
                if (play>= songs) {
                  play=0;
                }
              }
            }
          }
        }
      }
      //for (int i=0; i<c.length; i++) {
      //  for (int o=0; o<c.length; o++) {
      //    if (i !=o) {
      //      ellipse(hitsX[i][o], hitsY[i][o], 50, 50);
      //    }
      //  }
      //}
    
      if (keyPressed && key == 'p') delay(5000);
    
      strokeWeight(1);
      stroke(0);
      line(- width / 2, 0, width / 2, 0);
      line(0, - height / 2, 0, height / 2);
      println(count);
      textAlign(TOP, LEFT);
      stroke(0);
    }
    void intersectcalc() { 
      float tempA;
      float tempB; 
      float tempC;
    
      for (int i=0; i<c.length; i++) {
        for (int o=0; o<c.length; o++) {
          if (i !=o) {
            tempA=(a[i]-a[o]);
            tempB=(b[i]-b[o]);
            tempC=(c[i]-c[o]);
    
            if (o>i) {
              hitsX[i][o]=(((-1*tempB)+ (sqrt(sq(tempB)-(4*tempA*tempC))))/(tempA*2));
              hitsY[i][o]=a[i] * ( hitsX[i][o] *  hitsX[i][o]) + b[i] *  hitsX[i][o] + c[i];
            }
            if (o<i) {
              hitsX[i][o]=(((-1*tempB) + (sqrt(sq(tempB)-(4*tempA*tempC))))/(tempA*2));
              hitsY[i][o]=a[i] * ( hitsX[i][o] *  hitsX[i][o]) + b[i] *  hitsX[i][o] + c[i];
            }
          }
        }
      }
    }
    
Sign In or Register to comment.