I have a couple of questions about a school project I'm working on. The code is as follows.
public class Player
{
private PlayList playList;
private Track track;
/**
* Constructor ...
*/
public Player()
{
playList = new PlayList("audio");
track = playList.getTrack(0);
}
/**
* Return the track collection currently loaded in this player.
*/
public PlayList getPlayList()
{
return playList;
}
/**
*
*/
public void play()
{
track.play();
}
/**
*
*/
public void stop()
{
track.stop();
}
/**
*
*/
public void setTrack(int trackNumber)
{
int currentTrack = trackNumber;
track = playList.getTrack(currentTrack);
}
/**
*
*/
public String getTrackName()
{
String currentTrack = track.getName();
return currentTrack;
}
/**
*
*/
public String getTrackInfo()
{
String currentTrack = track.getName();
int trackDuration = track.getDuration();
return currentTrack + " " + "(" + trackDuration + ")";
}
}
public class Track
{
private Clip soundClip;
private String name;
/**
* Create a track from an audio file.
*/
public Track(File soundFile)
{
soundClip = loadSound(soundFile);
name = soundFile.getName();
}
/**
* Play this sound track. (The sound will play asynchronously, until
* it is stopped or reaches the end.)
*/
public void play()
{
if(soundClip != null) {
soundClip.start();
}
}
/**
* Stop this track playing. (This method has no effect if the track is not
* currently playing.)
*/
public void stop()
{
if(soundClip != null) {
soundClip.stop();
}
}
/**
* Reset this track to its start.
*/
public void rewind()
{
if(soundClip != null) {
soundClip.setFramePosition(0);
}
}
/**
* Return the name of this track.
*/
public String getName()
{
return name;
}
/**
* Return the duration of this track, in seconds.
*/
public int getDuration()
{
if (soundClip == null) {
return 0;
}
else {
return (int) soundClip.getMicrosecondLength()/1000000;
}
}
/**
* Set the playback volume of the current track.
*
* @param vol Volume level as a percentage (0..100).
*/
public void setVolume(int vol)
{
if(soundClip == null) {
return;
}
if(vol < 0 || vol > 100) {
vol = 100;
}
double val = vol / 100.0;
try {
FloatControl volControl =
(FloatControl) soundClip.getControl(FloatControl.Type.MASTER_GAIN);
float dB = (float)(Math.log(val == 0.0 ? 0.0001 : val) / Math.log(10.0) * 20.0);
volControl.setValue(dB);
} catch (Exception ex) {
System.err.println("Error: could not set volume");
}
}
/**
* Return true if this track has successfully loaded and can be played.
*/
public boolean isValid()
{
return soundClip != null;
}
/**
* Load the sound file supplied by the parameter.
*
* @return The sound clip if successful, null if the file could not be decoded.
*/
private Clip loadSound(File file)
{
Clip newClip;
try {
AudioInputStream stream = AudioSystem.getAudioInputStream(file);
AudioFormat format = stream.getFormat();
// we cannot play ALAW/ULAW, so we convert them to PCM
//
if ((format.getEncoding() == AudioFormat.Encoding.ULAW) ||
(format.getEncoding() == AudioFormat.Encoding.ALAW))
{
AudioFormat tmp = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
format.getSampleSizeInBits() * 2,
format.getChannels(),
format.getFrameSize() * 2,
format.getFrameRate(),
true);
stream = AudioSystem.getAudioInputStream(tmp, stream);
format = tmp;
}
DataLine.Info info = new DataLine.Info(Clip.class,
stream.getFormat(),
((int) stream.getFrameLength() *
format.getFrameSize()));
newClip = (Clip) AudioSystem.getLine(info);
newClip.open(stream);
return newClip;
} catch (Exception ex) {
return null;
}
}
}
public class PlayList
{
private List<Track> tracks;
/**
* Constructor for objects of class TrackCollection
*/
public PlayList(String directoryName)
{
tracks = loadTracks(directoryName);
}
/**
* Return a track from this collection.
*/
public Track getTrack(int trackNumber)
{
return tracks.get(trackNumber);
}
/**
* Return the number of tracks in this collection.
*/
public int numberOfTracks()
{
return tracks.size();
}
/**
* Load the file names of all files in the given directory.
* @param dirName Directory (folder) name.
* @param suffix File suffix of interest.
* @return The names of files found.
*/
private List<Track> loadTracks(String dirName)
{
File dir = new File(dirName);
if(dir.isDirectory()) {
File[] allFiles = dir.listFiles();
List<Track> foundTracks = new ArrayList<Track>();
for(File file : allFiles) {
//System.out.println("found: " + file);
Track track = new Track(file);
if(track.isValid()) {
foundTracks.add(track);
}
}
return foundTracks;
}
else {
System.err.println("Error: " + dirName + " must be a directory");
return null;
}
}
/**
* Return this playlist as an array of strings with the track names.
*/
public String[] asStrings()
{
String[] names = new String[tracks.size()];
int i = 0;
for(Track track : tracks) {
names[i++] = track.getName();
}
return names;
}
}
1. I understand that to call the play methods in the player class, I have to initialize a Track class variable. I also need to initialize it using the PlayList getTrack method. However, how can I initialize it without defining a starting index variable (i.e I don't want it to automatically initialize to a specific song in the index, I want the user to have to select a song first)?
2. Also, how do I code the play method in the player class to stop a existing song if one is playing before starting a new song and to restart a song if the play method is called again one the same song?