Triggering multiple sounds with SoundFile?

edited November 2015 in Library Questions

Hello ! I'm trying to make a simple program with multiple sound outputs using the SoundFile Library. I tried to make it so that at a particular hour, a sound file is played that lasts exactly one minute, and then at the start of the next minute, a new sound file is played to create the illusion of a continuous, but changing sound. However, when I run the program, it always plays the first sound right on time, but never plays the sound set to play when the first one ends- here is the code I've been trying to use.

import processing.sound.*;

import processing.sound.*; SoundFile file;

void setup() {

size(640, 500);

background(10,10,10);

}

void draw() {

int s = second(); // Values from 0 - 59

int m = minute(); // Values from 0 - 59

int h = hour(); // Values from 0 - 23

if(h == 21 && m == 28 && s == 0) {

noLoop();

file = new SoundFile(this, "900pm.mp3");

file.play();

}

if(h == 21 && m == 29 && s = 0) {

noLoop();

file = new SoundFile(this, "901pm.mp3");

file.play();

}

} It plays "90pm" at 9:00, but once it hits 9:01, it's silent. I am wondering if a) I should put the loading of the Soundfiles in setup, b) if this program is possible (should I be using Minim?) c) if there is some function that I am missing that will allow the program to keep sequencing a number of soundles one after the other, at the specific time. Thanks so much!

Tagged:

Answers

  • Your noLoop() function prevents code from running further, you don't need to use it.

    a. Yes, files should be loaded once in the setup. You can't see negative consequenses of loading file in draw() because of noLoop(). You'll need an array of SoundFile objects to assign your sounds to them. b. It should be possible with both minim and sound.

  • If I don't use the noLoop() function, the sound keeps starting infnitely- will loading the files in setup fix that as well?

  • edited November 2015

    No, it is only for performance issues. Is it really infinite? Without noLoop() your file.play() should be executed 60 times (default framerate). In order to avoid it, you need to use a boolean as a flag.

    boolean play = false;
    

    Then, you can make

    if (play){
    file.play();
    play = false;
    }
    

    When you set boolean play to be equal true, the code above will make sure that file.play(); is executed only once. If you use many sound files, you may want to move it to separate function that will be responsible for playing the needed sound or an array of booleans that correspond to file you want to play.

  • I have made a few changes to the code, and again it plays at the correct time, but with the boolean it still executes continuously, creating noise instead of the song. import processing.sound.*;

    SoundFile file;

    void setup() {

    size(650, 500);

    background(0);

    file = new SoundFile (this, "900pm.mp3");

    }

    void draw() {

    int h = hour();

    int m = minute();

    int s = second();

    if ( h == 14 && m == 14 && s == 0) {

    boolean play = true;

    if (play) {

    file.play();

    play = false;

    }

    }

    }

    Am I using it wrong? Also, I tried assigning numbers to the files like an array ( "file[1].play" or "file{2} = ...", etc) and it gave me an error saying that the expression was an array but resolved to SoundFile. Is there a specific way to assign numbers in SoundFile?

    Thanks for all your help so far, I'm sorry for the trouble!

  • edited November 2015 Answer ✓

    First, about single-time play

    boolean play = true;
    
    void setup() {
        size(650, 500);
        background(0);
        file = new SoundFile(this, "900pm.mp3");
    }
    
    void draw() {
    
        int h = hour();
        int m = minute();
        int s = second();
    
        if (h == 14 && m == 14 && s == 0 && play == true) {
            file.play();
            play = false;
        }
    }
    

    This should work, however there's a need to set boolean back to true, so next time at 14:14 it would work again, you can do something like this for example (somwhere at the end of code).

        if (h == 14 && m == 14 && s == 1){
            play = true;
        }
    
  • edited November 2015

    With arrays,

    SoundFile[] files = new SoundFile[2];
    boolean[] plays = new boolean[2];
    
    void setup() {
        size(650, 500);
        background(0);
    
        files[0] = new SoundFile(this, "900pm.mp3");
        files[1] = new SoundFile(this, "901pm.mp3");
    
        for (int i = 0; i < plays.length; i++) {
            plays[i] = true;
        }
    }
    
    void draw() {
    
        int h = hour();
        int m = minute();
        int s = second();
    
        if (h == 14 && m == 14 && s == 0 && plays[0] == true) {
            files[0].play();
            plays[0] = false;
        }
    
        if (h == 14 && m == 15 && s == 0 && plays[1] == true) {
            files[1].play();
            plays[1] = false;
        }
    }
    

    That is untested, but I hope works. And as with previous example, you need to set booleans to true, so next day it would work again:

    if (h == 23 && m == 59 && s == 59){
    for (int i = 0; i < plays.length; i++) {
            plays[i] = true;
        }
    }
    
  • I will test this out, thank you.

Sign In or Register to comment.