I have some problems to understand how to play some tracks
one after the other avoiding the overlap effect.
I am using the Minim library but I did not find a way
to detect the final moment of the first sound to start the second one.
Can anybody give me my some tips?
this is my sketch
import ddf.minim.*;
Minim minim;
AudioPlayer player[]=new AudioPlayer[4];
String filenames[] = new String[]{"sound1.mp3", "sound2.mp3"};
void setup(){
minim = new Minim(this);
for(int i=0;i<2;i++){
player[i] = minim.loadFile(filenames[i]);
player[i].play();
print(filenames);
}
}
void draw(){}
void stop(){
for(int i=0;i<2;i++){
player[i].close();
}
minim.stop();
super.stop();
}
You can poll player[i].isPlaying() to see if the sound is still playing before starting the next one. In your code, this means keeping track of which player is currently active, and moving the call to the .play() method into draw().
Related
I am made a door script and it works fine but now i want to add different sounds when the door opens and when it closes. I added an Audio Source at the door and added the doorOpen sound. How can i add a doorClose sound too and make it play via the script?
Audio Source
if (open) {
GetComponent<AudioSource>().Play ();
} else {
GetComponent<AudioSource>().Play ();
}
Check Audio & Sound Tutorial. Here is sample code:
using UnityEngine;
using System.Collections;
namespace Completed
{
public class SoundManager : MonoBehaviour
{
public AudioSource efxSource; //Drag a reference to the audio source which will play the sound effects.
public AudioSource musicSource; //Drag a reference to the audio source which will play the music.
public static SoundManager instance = null; //Allows other scripts to call functions from SoundManager.
public float lowPitchRange = .95f; //The lowest a sound effect will be randomly pitched.
public float highPitchRange = 1.05f; //The highest a sound effect will be randomly pitched.
void Awake ()
{
//Check if there is already an instance of SoundManager
if (instance == null)
//if not, set it to this.
instance = this;
//If instance already exists:
else if (instance != this)
//Destroy this, this enforces our singleton pattern so there can only be one instance of SoundManager.
Destroy (gameObject);
//Set SoundManager to DontDestroyOnLoad so that it won't be destroyed when reloading our scene.
DontDestroyOnLoad (gameObject);
}
//Used to play single sound clips.
public void PlaySingle(AudioClip clip)
{
//Set the clip of our efxSource audio source to the clip passed in as a parameter.
efxSource.clip = clip;
//Play the clip.
efxSource.Play ();
}
//RandomizeSfx chooses randomly between various audio clips and slightly changes their pitch.
public void RandomizeSfx (params AudioClip[] clips)
{
//Generate a random number between 0 and the length of our array of clips passed in.
int randomIndex = Random.Range(0, clips.Length);
Keep reference to both the Audio files.
Then,
if (open) {
GetComponent<AudioSource> ().clip = _OpenClip;
GetComponent<AudioSource> ().Play ();
} else {
GetComponent<AudioSource> ().clip = _CloseClip;
GetComponent<AudioSource> ().Play ();
}
I'm trying to play a sound, but it's not playing
Here's my code:
public void Replay()
{
playAudio ();
Application.LoadLevel (Application.loadedLevel);
}
void playAudio()
{
AudioSource audio = GetComponent<AudioSource> ();
audio.Play();
}
When a button clicked, I'm calling Replay(). But, the sound is not played.
If I remarkedApplication.LoadLevel (Application.loadedLevel);, the sound plays normally.
What should I do to make the sound play with Application.LoadLevel()?
The AudioSource playing the sound will get removed before it has time to finish.
Here is an alternative solution using yield to wait for the sound to finish.
public void Replay()
{
StartCoroutine("ReplayRoutine");
}
IEnumerator ReplayRoutine()
{
AudioSource audio = GetComponent<AudioSource>();
audio.Play();
yield return new WaitForSeconds(audio.clip.length);
Application.LoadLevel(Application.loadedLevel);
}
You call play method and you load the scene after it. Try to call playAudio() before loading level.
public void Replay() {
Application.LoadLevel(Application.loadedLevel);
playAudio();
}
I think you don't give the chance to the audio source to play the sound, because after executing play, you immediately re-loaded the scene, so the same instance of audio source does not exist anymore, a new instance is created which has not yet received the play command. You can use some small delay using co-routine or other ways to give the needed time to the audio source. ( If you want to play the sound before loading level, otherwise just play the sound in a Start() callback)
I was following closely the example given on "Programming Interactivity" by Joshua Nobel.
Ok. Basically what the example does is that it should play an mp3 file. I have already put "song.mp3" under the "data" folder. But when I tried to play the sketch, I am getting,
"cannot convert from AudioPlayer to AudioPlayer"
I can't seem to be able to see anyone who is having the same problem as me.
The below codes were executed on Processing IDE.
import ddf.minim.*;
AudioPlayer song;
Minim minim;
void setup() {
size(800, 800);
minim = new Minim(this);
song = minim.loadFile("song.mp3");
song.play();
}
Can someone please tell me why am I having this error?
I did this instead and it works!!!
import ddf.minim.*;
ddf.minim.AudioPlayer song;
I was wondering if there was a processing code that will let me use sound only when i press the mouse and stops when I release it. I already have the audio that I want to use loaded onto processing but I'm having difficulty finding the code. Please help me! Thank you!
Your question is very vague, but I'll do my best to answer.
I don't think there's any way to handle audio with Processing's built-in functions, but the minim library works well with it. I'm going to assume that's what you're using for this solution.
As I understand it, you'd like to press the mouse, start the sound, and when the mouse is released you'd like to stop the sound, rather than pause it. We can accomplish this using processing's built-in mousePressed and mouseReleased methods like so:
import ddf.minim.*;
Minim minim;
AudioPlayer player;
AudioInput input;
void setup()
{
//let's make the window a little bigger
size(400,400);
minim = new Minim(this);
player = minim.loadFile("song.mp3");
input = minim.getLineIn();
}
void draw(){ }
void mousePressed()
{
player.play();
}
void mouseReleased()
{
player.close();
//since close closes the file, we'll load it again
player = minim.loadFile("song.mp3");
}
The code for pausing would look very similar, except you would replace everything in the mouseReleased block with the following:
player.pause();
class MyCanvas extends Canvas{
protected void paint(Graphics g) {
//Process keyboard
//Update movement/position
//Draw
repaint(); //loop
}
}
Until now I used the Canvas's paint() for the game loop, but I came across some article in the web that says that another thread should be used here
Now I'm wondering if paint() is a good/safe place to process all the data.
So can I continue doing it like this?
Or should I make another thread for that?
I'm not sure of pros and cones of each so I'm not sure which method to choose but I got used to repaint method
I would not use paint() that way, no. paint() should be for painting ... drawing. I would split your monitoring of user input, and game logic processing, outside that method.
Have you considered using the GameCanvas subclass of Canvas?
It gives you some nice double-buffering features. You would create another thread, which would call your GameCanvas' run() method, where it would check for user input, update the game logic, then draw to the off-screen buffer, and finally trigger repainting of the on-screen buffer.
Something like this:
class MyGameCanvas extends GameCanvas implements Runnable {
/** start this game! */
public void start() {
Thread worker = new Thread(this);
worker.start();
}
/** run the game loop */
public void run() {
// Get the Graphics object for the off-screen buffer
Graphics g = getGraphics();
while (true) {
// Check user input and update positions if necessary
int keyState = getKeyStates();
if ((keyState & LEFT_PRESSED) != 0) {
sprite.move(-1, 0);
}
else if ((keyState & RIGHT_PRESSED) != 0) {
sprite.move(1, 0);
}
// Clear the background to white
g.setColor(0xFFFFFF);
g.fillRect(0,0,getWidth(), getHeight());
// Draw the Sprite
sprite.paint(g);
// Flush the off-screen buffer
flushGraphics();
try {
// TODO: of course, you might want a more intelligent
// sleep interval, that reflects the amount of time
// remaining (if any) in the cycle ...
Thread.sleep(10); //sleep 10 ms
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Note that I put basically everything in the run() method, for brevity. I'm assuming your game is more complicated, and would warrant splitting off separate methods for getting user input, updating logic, and then calling graphics/paint methods. Those would all be called from run().
Usage
Start this in your MIDlet's startApp() method:
MyGameCanvas gameCanvas = new MyGameCanvas();
gameCanvas.start();
exitCommand = new Command("Exit", Command.EXIT, 1);
gameCanvas.addCommand(exitCommand);
gameCanvas.setCommandListener(this);
Display.getDisplay(this).setCurrent(gameCanvas);
References
http://www.codeproject.com/Articles/35833/Programming-2D-Games-in-J2ME
an example that shows a better implementation, if you don't use GameCanvas and just use Canvas.
PowerPoint overview of Game APIs and looping , with code and general theory