Looping MP3 File

Hello! First I want to admit that I have absolutely no idea what I’m doing when it comes to playing sounds and music. I have been using an ogg sound library to loop ogg files in my program, but the licenses for the music I am using require that they remain unmodified, meaning I must use MP3 format.

So that’s my dilemma. I have implemented a barebones MP3 class (which uses JLayer) I found through Google, which can be found here: http://www.cs.princeton.edu/introcs/faq/mp3/mp3.html.

This works fine, however I cannot for the life of me seem to get it to loop. I don’t think I know enough about the inner workings of sound files and sound interfaces to be able to figure it out on my own.

Any help would be appreciated!

Just as an aside. This is for a 2-d game that I am creating for a senior project at the college I go to, and when finished I will make it open-source. I have been working on it for a year now and I seem to be able to manage everything else in the game just fine, it’s just the music that’s stopping me. The game plays great without music, but who wants to play a game like that?

It figures, after having been stuck on this problem for months I finally decide to post about it, then I come up with a solution.

Here is the code for anyone else who’s curious, and if anyone knows a better way to do this then by all means please let me know!


import java.io.BufferedInputStream;
import java.io.FileInputStream;

import javazoom.jl.player.Player;

public class MP3Player extends Thread
{
	private String filename;
	private Player player; 
	private Thread mp3Thread;
	private boolean playing;
	private boolean locked;
    
	// constructor that takes the name of an MP3 file
	public MP3Player() 
	{
		this.filename = "";
		mp3Thread = null;
		playing = true;
		locked = true;
	}
	
	public void run()
	{
		while (playing)
			play();
	}

	public void play() 
	{
		if (!locked)
		{
			if (filename != null && filename != "")
			{
				try
				{
					FileInputStream fis     = new FileInputStream(filename);
					BufferedInputStream bis = new BufferedInputStream(fis);
					player = new Player(bis);
					
					mp3Thread = new Thread() 
					{
						public void run() 
						{ try { player.play(); } catch (Exception e) { System.out.println(e); } }
					};
				
					mp3Thread.start();
					mp3Thread.join();
				} catch (Exception e) { System.out.println(e); }
			}
		}
	}

	public void changeMusic(String newGuy)
	{
		locked = true;
		filename = "";
		try
		{
			if (player != null)
				player.close();
			mp3Thread = null;
			
			filename = ".\\music/" + newGuy + ".mp3";
			
			locked = false;
		}
		catch (Exception e) {}
	}
	
	public void close() 
	{
		locked = true;
		playing = false; 
		
		try 
		{ 
			if (player != null) 
				player.close(); 
			
			if (mp3Thread != null)
				mp3Thread = null;
		} catch (Exception e) {}
	}
	
}

Your source wasn’t exactly complete. I found this online… It maybe be for school’s site where they posted your project

http://www.cs.princeton.edu/introcs/faq/mp3/mp3.html

/*************************************************************************
 *  Compilation:  javac -classpath .:jl1.0.jar MP3.java         (OS X)
 *                javac -classpath .;jl1.0.jar MP3.java         (Windows)
 *  Execution:    java -classpath .:jl1.0.jar MP3 filename.mp3  (OS X / Linux)
 *                java -classpath .;jl1.0.jar MP3 filename.mp3  (Windows)
 *  
 *  Plays an MP3 file using the JLayer MP3 library.
 *
 *  Reference:  http://www.javazoom.net/javalayer/sources.html
 *
 *
 *  To execute, get the file jl1.0.jar from the website above or from
 *
 *      http://www.cs.princeton.edu/introcs/24inout/jl1.0.jar
 *
 *  and put it in your working directory with this file MP3.java.
 *
 *************************************************************************/

import java.io.BufferedInputStream;
import java.io.FileInputStream;

import javazoom.jl.player.Player;


public class MP3 {
    private String filename;
    private Player player; 

    // constructor that takes the name of an MP3 file
    public MP3(String filename) {
        this.filename = filename;
    }

    public void close() { if (player != null) player.close(); }

    // play the MP3 file to the sound card
    public void play() {
        try {
            FileInputStream fis     = new FileInputStream(filename);
            BufferedInputStream bis = new BufferedInputStream(fis);
            player = new Player(bis);
        }
        catch (Exception e) {
            System.out.println("Problem playing file " + filename);
            System.out.println(e);
        }

        // run in new thread to play in background
        new Thread() {
            public void run() {
                try { player.play(); }
                catch (Exception e) { System.out.println(e); }
            }
        }.start();




    }


    // test client
    public static void main(String[] args) {
        String filename = args[0];
        MP3 mp3 = new MP3(filename);
        mp3.play();

        // do whatever computation you like, while music plays
        int N = 4000;
        double sum = 0.0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                sum += Math.sin(i + j);
            }
        }
        System.out.println(sum);

        // when the computation is done, stop playing it
        mp3.close();

        // play from the beginning
        mp3 = new MP3(filename);
        mp3.play();

    }

}

Meself, I’d have just found some music without such a daft license restriction and used that instead in OGG format :slight_smile: No need to make work for yourself!

Cas :slight_smile:

MP3 isn’t suited for looping, since the decoded audio contains varying amounts of leading and trailing silence. You either have to specify the lead-in and lead-out points per file - or write some logic which does this for you.

Using Ogg is of course the smarter option. You get proper looping and a better size/quality ratio there.