简体   繁体   中英

How to play a wav file with no lag?

I've looked around the internet on ways to play wav files, but I have found that they do not play on a separate thread and so cause the program to halt until the song is done, which does not work for a game. However, when I try to play everything on a separate thread, it lags. Does anyone have a fix for this?

Note: I also am painting on to the background continuously:

public class DrawThread extends Thread {

    JFrame j;

    public DrawThread(JFrame frame) {
        j = frame;
    }

    public void run() {
        while (!(isInterrupted())) {
            if (j.isDisplayable() && j.isActive() && j.isEnabled())
            j.update(j.getGraphics());
        }
    }

}

and update just calls paint which is:

public void paint(Graphics g) {
            Graphics2D bg = (Graphics2D) g;
    bg.setBackground(Color.black);
    int w = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    int h = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
    if (time < 500) {
        x[time] = r.nextInt(w) + 150;
        y[time] = h;
        z[time] = r.nextInt(w) + 150;
        time++;
    }
    for (int i = 0; i < time; i++) {
        y[i] -= forward;
        x[i] -= right;
        if (y[i] < 1) {
            x[i] = r.nextInt(400) - 200;
            y[i] = 300;
            z[i] = r.nextInt(400) - 200;
        } else if (y[i] > 300) {
            x[i] = r.nextInt(400) - 200;
            y[i] = 1;
            z[i] = r.nextInt(400) - 200;
        }
        if (x[i] > 200)
            x[i] = -200;
        else if (x[i] < -200)
            x[i] = 200;
        bg.setColor(color);
        bg.drawLine(
                getWidth() / 2 + (int) Math.round(x[i] * 200 / y[i]),
                getHeight() / 2 + (int) Math.round(z[i] * 200 / y[i]),
                getWidth()
                        / 2
                        + (int) Math.round((x[i] + right) * 200
                                / Math.abs(y[i] + forward)),
                getHeight()
                        / 2
                        + (int) Math.round((z[i]) * 200
                                / Math.abs(y[i] + forward)));
    }
}

EDit: Adding the music player class I'm using (I've switched to BigClip):

import java.io.File;
import java.util.Collection;
import java.util.HashMap;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

import org.crystalix.util.SoundListener;

public class MSHandler {
public static boolean pause = false;
public static boolean stop = false;
private static HashMap<String, BigClip> clips = new HashMap<String, BigClip>();

public static void stopAll() {
    Collection<BigClip> c = clips.values();
    for (BigClip b : c) {
        System.out.println("Stopping "+b.toString());
        b.stop();
        System.out.println("Stopped "+b.toString());
    }
}

public static void playMusic(File file) {
    try {
        AudioInputStream audioIn = AudioSystem.getAudioInputStream(file);
        BigClip clip = new BigClip();
        clip.open(audioIn);
        clip.addLineListener(new SoundListener());
        clip.loop(1);
        clip.start();
        clips.put(file.getName(), clip);
    } catch (Exception e) {
        System.err.println("Sound could not be started!");
        e.printStackTrace(System.err);
    }
}
}

You haven't shown the code you are using for the wav file playback. That makes it a bit hard to diagnose what might be going wrong!

1) The wav should simply be on its own thread. If you do so correctly, it will not block anything else. The Java sound tutorials don't do a particularly good job of pointing this out. So: put the code that calls the wav playback in its own runnable and you should be okay.

2) You can "open" the wav prior to the time when you wish to play it. Then, it should "start" right away when you finally tell it to go.

Another note: the code that plays back a wav file runs more quickly if it is already in memory. So, sometimes the first wav playback only starts after a slight hesitation. But it is possible to combat this by playing another sound at zero volume to get the sound playback code into memory. I often do this at the start of programs that have sound.

The continuous painting in the background is only an issue if you are using up so many cpus that the JVM doesn't have time to process the sound. I'd really be surprised if that was the issue. If it were, what you'd probably hear is the sound playback with lots of clicks in it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM